私はjavascript、node.js、mochaなどすべてに比較的初心者です。
私のコードには、disabledプロパティをtrueに設定するdisable()
とdisabledプロパティを返すisDisabled()
を持つUnitオブジェクトがあります。また、次のターンの開始時にユニットをリセットするメソッドnextTurnReset()
もあります。この動作をテストするためのテストスイートを作成しました。最初にオブジェクトを無効にしてから、テストして無効になっているかどうかを確認します。ただし、最初のテスト内のユニット変数(Mochaのit()
メソッドに渡された無名関数内)は、ノードのデバッガーで観察したように、無効化されていない状態です。
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);
});
});
記録として、最初の2つのテストは失敗し、最後のテストは成功して、ユニットがまったく無効にされていないことを示します。
ノードデバッガーのreplの使用から:最初のdebugger;
ステートメントの後unit.disabled == true
、ただし2番目のdebugger;
ステートメントunit.disabled == false
の後。どちらの場合も、値はtrueになると思います。
なぜこれが当てはまるのか考えはありますか?また、期待される結果を得るためにMochaテストを作成する正しい方法は何ですか?
本当にありがとう!
Mochaの変数スコープは、他のJavaScriptコードとまったく同じです。問題は、Mochaがコードを実行する順序がわからないことです。これが起こることです:
ユニットインスタンスを作成し、それに対してdisable
を呼び出します。
最初のテストを登録します。それがit
が行うことです。future実行のテストを登録します。テスト現在は実行されません。
unit.nextTurnReset();
を呼び出すと、オブジェクトの状態がリセットされます。
2番目のテストを登録します。再び今は実行されません。
オブジェクトを再度リセットします。
最後のテストを登録します。
この後、Mochaは登録したテストを取得して実行します。 テストが実行されるまでに、オブジェクトはリセット状態になり、無効にはなりません。
あなたが説明する望ましい振る舞いを考えると、あなたのコードは次のようになります:
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
に渡されたコードは、登録した各テストの前に実行されるため、適切なタイミングでオブジェクトがリセットされます。
例間で状態を渡すことは、あまり良い習慣ではありません。ランダムな順序でテストを実行する必要がある場合はどうなりますか?または、プロジェクトの誰かが例を移動することにしましたか?
私にとって、次の2つの例があると、Unit#disableを適切にテストするのに十分なようです。
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);
});
});