variables作用域如何在Mochatesting框架内工作?

我是一个JavaScript,node.js,摩卡等所有东西的相对新手。

在我的代码中,我有一个单元对象有一个disable() ,设置禁用属性为true和isDisabled() ,返回禁用的属性。 它也有一个方法nextTurnReset() ,在下一回合开始时重置单位。 我写了一个testing套件来testing这种行为。 我首先禁用对象,然后尝试testing以查看它是否被禁用。 但是,我的第一个testing中的单元variables(在传递给Mocha的it()方法的匿名函数中it()处于非禁用状态,正如我在节点的debugging器中观察到的那样。

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

为logging,前两个testing失败,最后一个成功,表明该单位从来没有被禁用。

从使用节点debugging器的repl:在第一个debugger; 声明, unit.disabled == true ,但在第二个debugger; 语句unit.disabled == false 。 我期望在这两种情况下,这个值都是正确的。

不知道为什么会这样? 另外,写摩卡testing的正确方法是什么?

非常感谢!

Mocha中的variables范围与其他任何JavaScript代码完全相同。 你的问题是,你不知道摩卡将执行你的代码的顺序。 这是发生了什么事情:

  1. 你创build你的单元实例并调用它的disable

  2. 你注册你的第一个testing。 这就是it所做的:为未来执行注册一个testing。 testing现在不执行

  3. 你可以调用unit.nextTurnReset(); 这会重置您的对象的状态。

  4. 你注册你的第二个testing。 它现在不再执行

  5. 你再次重置你的对象。

  6. 你注册你的最后一个testing。

在此之后,摩卡接受你注册的testing并运行它们。 当你的testing运行时,你的对象处于复位状态,而不是被禁用。

在我看来,鉴于你所描述的期望的行为,你的代码应该是:

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

传递给beforeEach的代码在每个你已经注册的testing之前运行,以便在正确的时间重置对象。

在示例之间传递状态不是一个很好的做法。 如果您需要按随机顺序运行testing,会发生什么情况? 或者项目中的某个人决定转移范例?

对于我来说,以下两个例子似乎足以正确testingUnit#的禁用

 describe('#disable()', function() { it('gets disabled when called on an enabled', function() { var unit = tests.newUnit(); unit.disable(); (unit.isDisabled()).should.be.exactly(true); }); it('gets enabled when called on a disabled', function() { var unit = tests.newUnit(); unit.disable(); unit.disable(); (unit.isDisabled()).should.be.exactly(false); }); });