私は、多数のテストに対して実行する必要がある JavaScript プログラムの作成者です。これらの各テストは同様の形式に従っているため、ファクトリ関数を使用してテストを生成するのが適切であることがわかりました。
ファクトリ関数は testFactory と呼ばれ、以下のコードに示されています。アプリケーションロジックが追加されると、特定のテストを構築する方法をファクトリに指示するデータ配列で呼び出されます。factory 関数は、テストの実行も担当します。
ファクトリに渡されるデータに「遅延」文字列が含まれている場合に 2 秒の遅延を実現するために、RxJS を選択しました。(前回の実装では promise を使用しましたが、このアプローチを機能させることに失敗しました。) ご覧のとおり、これは Rx 遅延演算子を使用して達成されます。
AvaはRxJSとの連携に定評があるため選ばれました。ご覧のとおり、サブスクリプションからオブザーバブルへの Rx サブジェクトを呼び出しています。
実際のアプリケーション コードでは、このサブスクリプションはアプリケーション ロジックを実装するステート マシンを呼び出し、ステート マシンからのデータは、ステート マシンのコールバック メソッドでサブジェクトの次のメソッドを呼び出すことによってサブジェクトに供給されます。これが、オブザーバブルを直接 Ava テスト メソッドに単純にプラグインすることができず、代わりにサブジェクトを通過する必要がある理由です。オブザーバブルの代わりにサブジェクトが選択されたのは、サブジェクトがその定義の外から次の完全なメソッドを呼び出すことができるようにするためです。
問題をこれらの詳細と混同しないように、以下のコードからアプリケーション ロジックを削除しました。問題は、「遅延」文字列がデータ配列から削除されたときに発生します。遅延を含まないデータでこのコードを実行すると、テストに合格しません。
const data = [
{ r: 'c' },
{ l: 'c' },
{ l: 'n' },
{ l: 'c' }
];
次のエラーで失敗します。Test finished without running any assertions.
データ配列に「遅延」がない場合、どうすればこのパスを取得できますか? データ配列に「遅延」がない場合、これが失敗するのはなぜですか? ありがとうございました。
const ava = require('ava');
const { test } = ava;
const Rx = require('rxjs/Rx');
const { Observable, Subject } = Rx;
const data = [
{ r: 'c' },
{ l: 'c' },
{ l: 'n' },
'delay',
{ l: 'c' }
];
const testFactory = (data) => {
let subject = new Subject();
// This code adds a delay property to each item which passes through, adding a
// delay value based on a cumulative delay value maintained by the scan
// operator. Items which are simply delays are marked with a 'skip' property
// in the scan and skipped in the flatMap. Once the delay has been performed
// by the delay operator, the added delay property is deleted. If there is a
// simpler way in Rx to achieve this functionality, I'm open to suggestions
// on refactoring this code. :-)
const source = Observable.from(data)
.scan((acc, val) => {
if (val === 'delay') {
return { skip: true, delay: acc.delay + 2000 };
}
return Object.assign(val, { delay: acc.delay });
}, { delay: 0 })
.flatMap((e) => {
if (e.skip) {
return Observable.empty();
} else {
return Observable.of(e)
.delay(e.delay)
.map(e => { delete e.delay; return e; });
}
});
// This is the subscribe block which in my application called my state
// machine. Since the state machine has been removed, the Subject is called
// directly, instead of calling it from the callback tot the state machine.
// Either way, the same problem exists.
source
.subscribe({
next: e => {
subject.next(e);
},
complete: () => {
subject.complete();
}
});
// This test always passes. When the 'delay' is removed, the failure would
// indicate to me that its never called.
test('', t => {
// t.plan(1);
return subject
.map((n) => {
t.true(true);
});
});
};
testFactory(data);
注: 興味深いことに、Ava のインポートが Ava のテスト関数をインポートする以下の行と共に削除され、テスト関数の呼び出しがサブジェクトの通常の RxJS サブスクライブに置き換えられると、コードは「遅延」の有無にかかわらず機能します。 ' データ構造内の文字列:
// test('', t => {
// // t.plan(1);
// return subject
// .map((n) => {
// t.true(true);
// });
// });
subject.subscribe((v) => {
console.log(JSON.stringify(v));
});
これは、Ava の使用に問題があることを示していますか?