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 の計算はfalsebar は再実行されず失敗
する baz の計算はfalse
baz の計算はtrue
cat の計算はfalsecat は再実行されず失敗
する
fooとではなくにbaz反応しました。barcat
私は他の 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ます。そのような方法で回答しないでください。