The following test code, written using Mocha.js fails. I expect the someVal to be increased 3 times and equal 3 in the last test. The issue came up in more complex
this
is not what you think it is. this
gets redefined in every function() {}
block (unless Mocha calls them in some specific way I'm not familiar with).
What you want is to use scope in your advantage:
describe('increasing 3 times', function() {
var someVal; // Initialization.
before(function() {
someVal = 0; //No need to return from before()
});
beforeEach(function() {
someVal += 1;
});
describe('going deeper', function() {
before(function() {
someVal += 1;
});
beforeEach(function() {
someVal += 1;
});
return it('has increased someVal to 3', function() {
someVal.should.equal(3);
});
});
});
Also, you don't need to return
so much. In fact, you almost never have to return in test code.
I don't know of any version of Mocha that would run the code you show in your question without error. For your code to work, it would have to be written like this:
require("chai").should();
describe('increasing 3 times', function() {
before(function() {
this.someVal = 0;
});
beforeEach(function() {
this.someVal += 1;
});
describe('going deeper', function() {
var parent_ctx = this.parent.ctx;
before(function() {
parent_ctx.someVal += 1;
// The line above is equivalent to this:
// this.test.parent.ctx.someVal += 1;
});
beforeEach(function() {
parent_ctx.someVal += 1;
});
it('has increased someVal to 3', function() {
parent_ctx.someVal.should.equal(3);
// The above line is equivalent to this:
// this.test.parent.parent.ctx.someVal.should.equal(3);
});
});
});
Inside the function passed to describe
and the functions passed to the hooks of a describe
block (before
, beforeAll
, etc.) the value of this
is a "context" object which is the same for the describe
and all of its own hooks (not the hooks of other describe
calls nested in it). So when you assign to this
, it assigns to the context. If you want to access this context inside nested calls to describe
or in tests you have to walk up the tree of describe
and test objects.
I would do it exactly the same way Second Rikudo suggested: use a variable scoped to your uppermost describe
call. For the sake of completeness:
require("chai").should();
describe('increasing 3 times', function() {
var someVal;
before(function() {
someVal = 0;
});
beforeEach(function() {
someVal += 1;
});
describe('going deeper', function() {
before(function() {
someVal += 1;
});
beforeEach(function() {
someVal += 1;
});
it('has increased someVal to 3', function() {
someVal.should.equal(3);
});
});
});