Jasmine で反応性をテストすると、いくつかの Tracker 計算が非常に興味深い方法で動作し始めました。ちょうど半分の計算が反応し、残りの半分はそうではありません。
この動作をテストするために私が行ったことは次のとおりです。
//In a describe block
var foo = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) {
Tracker.autorun(function observeFoo(fooComputation) {
var fooValue = foo.get();
console.log('foo in its computation is', fooValue);
if ( fooValue === true ) {
fooComputation.stop();
done();
}
});
setTimeout(function setFoo() {
foo.set(true);
}, 100);
});
だから基本的に:
foo
リアクティブを に初期化しfalse
ます。- 追跡を開始し、到達するのを待っ
true
て、テストがdone()
. - タイムアウトを使用し
foo.set(true)
てテストを解決します。 - もう必要ないので、この計算を停止します。
では、別の変数を使用してまったく同じことを行いましょう。
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) { /* ... */ });
it('should react to the changes of bar (2)', function(done) {
Tracker.autorun(function observeBar(barComputation) {
var barValue = bar.get();
console.log('bar in its computation is', barValue);
if ( barValue === true ) {
barComputation.stop();
done();
}
});
setTimeout(function setBar() {
bar.set(true);
}, 100);
});
そこから楽しみが始まります。このテストはまったく同じコードですが、名前が異なり、まったく同じロジックが記述されていますが、計算追跡バーが再実行されないため失敗します。
はconsole.log
それを非常によく示しています:
その計算における fooは: その計算
false
における foo は:true
- 反応性が開始されました!
その計算の棒は:false
[Nothing]
foo
の計算が再実行され、テストが完了したことは明らかですが、 の計算bar
は決して無効にされないため、テストは失敗します。
ただし、これで終わりではありません。新しいリアクティブ変数 (たとえばbaz
) に 3 番目のテスト ケースを追加し、前と同じ手順に従うと (他の変数で初期化し、同じdescribe
関数の最後にテストを追加する)、完全に機能します。
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false),
baz = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) { /* ... */ });
it('should react to the changes of bar (2)', function(done) { /* ... */ });
it('should react to the changes of baz (3)', function(done) { /* ... */ });
ここで、テストは(1)
成功し、テスト(2)
は失敗し、テストは(3)
成功します。
cat
ここで、同じ手順に従って、たとえば新しいものを使用して 4 番目のテストを追加すると、テスト(4)
は次のログで失敗します。
foo の計算は
false
foo の計算はtrue
bar の計算はfalse
bar は再実行されず失敗
する baz の計算はfalse
baz の計算はtrue
cat の計算はfalse
cat は再実行されず失敗
する
foo
とではなくにbaz
反応しました。bar
cat
私は他の 2 つ (5 番目と 6 番目) でそれを実行しましたが、同じ結果:(5)
成功し、(6)
失敗しました。
「奇数」のテストは成功し、「偶数」のテストは失敗します。
完全再現コード:
describe('Tracker usage with Jasmine', function() {
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false),
baz = new ReactiveVar(false),
cat = new ReactiveVar(false),
pup = new ReactiveVar(false),
elf = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) {
Tracker.autorun(function observeFoo(fooComputation) {
var fooValue = foo.get();
console.log('foo in its computation is', fooValue);
if ( fooValue === true ) {
fooComputation.stop();
done();
}
});
setTimeout(function setFoo() {
foo.set(true);
}, 100);
});
it('should react to the changes of bar (2)', function(done) {
Tracker.autorun(function observeBar(barComputation) {
var barValue = bar.get();
console.log('bar in its computation is', barValue);
if ( barValue === true ) {
barComputation.stop();
done();
}
});
setTimeout(function setBar() {
bar.set(true);
}, 100);
});
it('should react to the changes of baz (3)', function(done) {
Tracker.autorun(function observeBaz(bazComputation) {
var bazValue = baz.get();
console.log('baz in its computation is', bazValue);
if ( bazValue === true ) {
bazComputation.stop();
done();
}
});
setTimeout(function setBaz() {
baz.set(true);
}, 100);
});
it('should react to the changes of cat (4)', function(done) {
Tracker.autorun(function observeCat(catComputation) {
var catValue = cat.get();
console.log('cat in its computation is', catValue);
if ( catValue === true ) {
catComputation.stop();
done();
}
});
setTimeout(function setCat() {
cat.set(true);
}, 100);
});
it('should react to the changes of pup (5)', function(done) {
Tracker.autorun(function observePup(pupComputation) {
var pupValue = pup.get();
console.log('pup in its computation is', pupValue);
if ( pupValue === true ) {
pupComputation.stop();
done();
}
});
setTimeout(function setPup() {
pup.set(true);
}, 100);
});
it('should react to the changes of elf (6)', function(done) {
Tracker.autorun(function observeElf(elfComputation) {
var elfValue = elf.get();
console.log('elf in its computation is', elfValue);
if ( elfValue === true ) {
elfComputation.stop();
done();
}
});
setTimeout(function setElf() {
elf.set(true);
}, 100);
});
});
なぜこうなった?これらすべてのリアクティブ変数を同じ関数
に保持しながら、この問題を解決するにはどうすればよいですか?describe
ネストされたdescribe
関数を追加しようとしましたが、成功しませんでした。
この問題は、関連のない関数でテストを分離すると魔法のように消えdescribe
ます。そのような方法で回答しないでください。