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代码完全相同。 你的问题是,你不知道摩卡将执行你的代码的顺序。 这是发生了什么事情:
-
你创build你的单元实例并调用它的
disable
。 -
你注册你的第一个testing。 这就是
it
所做的:为未来执行注册一个testing。 testing现在不执行 。 -
你可以调用
unit.nextTurnReset();
这会重置您的对象的状态。 -
你注册你的第二个testing。 它现在不再执行 。
-
你再次重置你的对象。
-
你注册你的最后一个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); }); });