Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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 scenario where I used value set in outer before block to set up another in inner beforeEach block. Simplified case:

describe('increasing 3 times', function() {
  before(function() {
    this.instanceThis = this;
    return this.someVal = 0;
  });
  beforeEach(function() {
    return this.someVal += 1;
  });
  return describe('going deeper', function() {
    before(function() {
      return this.someVal += 1;
    });
    beforeEach(function() {
      return this.someVal += 1;
    });
    return it('has increased someVal to 3', function() {
      return this.someVal.should.equal(3);
    });
  });
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
605 views
Welcome To Ask or Share your Answers For Others

1 Answer

Explanation

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.

Solution

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);
        });
    });
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...