How does variable scope work within the Mocha test framework?

12,035

Variable scoping in Mocha is exactly the same as in any other JavaScript code. Your problem is that you do not realize in which order Mocha will execute your code. This is what happens:

  1. You create your unit instance and call disable on it.

  2. You register your first test. That's what it does: it registers a test for future execution. The test does not execute now.

  3. You call unit.nextTurnReset(); which resets your object's state.

  4. You register your second test. Again it does not execute now.

  5. You reset your object again.

  6. You register your last test.

After this, Mocha takes the tests you registered and runs them. By the time your tests are running your object is in its reset state, not disabled.

It seems to me that given the desired behavior you describe, your code should be:

describe('#disable()', function() {
    var unit = tests.newUnit();

    beforeEach(function () {
        unit.nextTurnReset();
    });

    it('disabled off turn?', function() {
        unit.disable();
        (unit.isDisabled()).should.be.exactly(true);
    });

    it('disabled on next turn?', function() {
        (unit.isDisabled()).should.be.exactly(false);
    });
});

The code passed to beforeEach is run before each test you've registered so it resets the object at the right time.

Share:
12,035

Related videos on Youtube

mcverry
Author by

mcverry

Updated on June 04, 2022

Comments

  • mcverry
    mcverry almost 2 years

    I am a relative newbie to all things javascript, node.js, mocha etc.

    In my code I have a Unit object that has a disable() that sets the disabled property to true and a isDisabled() that returns the disabled property. It also has a method nextTurnReset() that resets the unit on the start of the next turn. I have written a test suite to test this behavior. I first disable the object and then try to test to see if it is disabled. However, the unit variable inside my first test - which is within the anonymous function passed to the Mocha's it() method - is in the the non-disabled state as I observed with node's debugger.

    describe('#disable()', function() {
        var unit = tests.newUnit();
        unit.disable();
        debugger;
        it('disabled off turn?', function() {
            debugger;
            (unit.isDisabled()).should.be.exactly(true);
        });
        unit.nextTurnReset();
        it('disabled on next turn?', function() {
            (unit.isDisabled()).should.be.exactly(true);
        });
        unit.nextTurnReset();
        it('disabled on 2nd turn?', function() {
            (unit.isDisabled()).should.be.exactly(false);
        });
    });
    

    for the record, the first two tests fail, and the last one succeeds indicating the unit is never disabled at all.

    from using the node debugger's repl: After the first debugger; statement, unit.disabled == true, but after the second debugger; statement unit.disabled == false. I expect the value to true in both cases.

    Any idea why this would be the case? Also, what is the correct way of writing Mocha tests to get my expected result?

    Thanks so much!

  • Louis
    Louis over 6 years
    The OP was doing it incorrectly, but resetting a fixture to a known state between tests is an entirely valid strategy. If the creation of the whole fixture is not onerous, I do prefer to create it anew in each test, but sometimes it is preferable to reset to a known state between test rather than create expensive fixtures anew. Calling unit.nextTurnReset() in a beforeEach hook resets the test fixture to a known state between tests. Since it is in the beforeEach hook, the call to unit.nextTurnReset() before each test is not dependent on which tests run or don't run, or test order.