[解決済み] Jestにアサーションを期待する前に、すべての非同期コードの実行終了を待たせる方法
質問
私はReactアプリケーションの統合テスト、すなわち、多くのコンポーネントを一緒にテストするテストを書いています。
問題は、非同期コールバックが実行される前にテストが実行されるようで、私のテストが失敗することです。
これを回避する方法はありますか?私はどうにかして非同期コードが終了するのを待つことができますか?
以下は、いくつかの悪い 疑似 のコードで、私の主張を説明します。
親コンポーネントをマウントすると、子コンポーネントが外部サービスから戻ってきたコンテンツをレンダリングすることをテストしたいと思いますが、これはモックにします。
class Parent extends component
{
render ()
{
<div>
<Child />
</div>
}
}
class Child extends component
{
DoStuff()
{
aThingThatReturnsAPromise().then((result) => {
Store.Result = result
})
}
render()
{
DoStuff()
return(<div>{Store.Result}</div>)
}
}
function aThingThatReturnsAPromise()
{
return new Promise(resolve =>{
eternalService.doSomething(function callback(result) {
resolve(result)
}
}
}
これをテストで実行すると、コールバックが起動される前にItが実行されてしまうので失敗します。
jest.mock('eternalService', () => {
return jest.fn(() => {
return { doSomething: jest.fn((cb) => cb('fakeReturnValue');
});
});
describe('When rendering Parent', () => {
var parent;
beforeAll(() => {
parent = mount(<Parent />)
});
it('should display Child with response of the service', () => {
expect(parent.html()).toMatch('fakeReturnValue')
});
});
これをどのようにテストすればいいのでしょうか?私はangularがzonejsでこれを解決することを理解していますが、Reactに同等のアプローチはありますか?
どのように解決するのですか?
Jest 27+に更新しました。
jest 27+ではprocess.nextTickも使用可能です。
await new Promise(process.nextTick);
(コメントでAdrian Godongに感謝)
オリジナルの回答
保留中のPromiseが解決されるまで待機するスニペットがあります。
const flushPromises = () => new Promise(setImmediate);
なお setImmediate は非標準の機能であることに注意してください (そして、標準になることは期待されていません)。しかし、もしあなたのテスト環境で十分であれば、良い解決策になるはずです。その説明です。
このメソッドは、長時間実行される処理を分割し、ブラウザがイベントや表示の更新など他の処理を完了した直後にコールバック関数を実行するために使用されます。
async/awaitを使った使い方を大まかに説明します。
it('is an example using flushPromises', async () => {
const wrapper = mount(<App/>);
await flushPromises();
wrapper.update(); // In my experience, Enzyme didn't always facilitate component updates based on state changes resulting from Promises -- hence this forced re-render
// make assertions
});
私はこれをよく使いました このプロジェクトでは を使用しました。
関連
-
[解決済み】Reactコンポーネント内でswitchステートメントを使用するには?
-
[解決済み] React.createElement: type is invalid -- expected a string.
-
[解決済み] ReactJS giving error Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。
-
[解決済み] マテリアルUIセレクトフィールドのマルチセレクト
-
[解決済み] Webpack + Babelです。プリセット "es2015 "がディレクトリに相対して見つからなかった
-
[解決済み] リアクトです。<tr>は<td>の子として表示できません。コメント > td > tr を参照してください。
-
[解決済み] Webpack のコンパイルに失敗した
-
[解決済み] axios-mock-adapter onGet mock data not effective.
-
React はエラー TypeError を報告します。未定義のプロパティ 'XX' を読み取ることができない、問題は解決されました。
-
[解決済み] AxiosにCORSの問題が発生
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Reactを使用したMapBoxのCSSが欠落している件
-
[解決済み】Warning.Itが表示されるのはなぜですか?Functions are not valid as a React child?
-
[解決済み] FontAwesomeの無料パッケージに含まれているアイコンのオブジェクト名はどこにあるのですか?
-
[解決済み] Next.jsでWebSocketを利用する
-
[解決済み] MUI Boxは何のためのコンポーネントですか?
-
[解決済み] 非必須項目に対するYupバリデーション
-
[解決済み] Webpack のコンパイルに失敗した
-
[解決済み] sh: react-scripts: npm start の実行後にコマンドが見つからない。
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] react.jsで複数のモジュールをエクスポートする