はじめに
テストツールはjestです。
テストしたいコード
export let text = "hoge";
const asyncFunc = async () => {
await new Promise((resolve) => {
console.log(text);
// hoge
resolve();
});
text = "fuga";
console.log(text);
// fuga
};
const testFunc = () => {
asyncFunc();
console.log(text);
// hoge
};
export default testFunc;
testFunc
の中で非同期関数のasyncFunc
が実行されています。
testFunc
が実行されると、非同期でtext
の値がhoge
からfuga
に変わることをテストしたい。
テストコード
失敗例
test("testFunc", async () => {
testFunc();
expect(text).toBe("fuga");
});
このテストだと失敗します。
text="fuga"
を実行しているasyncFunc
が非同期だからですね。
成功例
test("testFunc", async () => {
testFunc();
expect(text).not.toBe("fuga");
return new Promise((resolve) => setImmediate(resolve)).then(() => {
expect(text).toBe("fuga");
});
});
これでテストが成功します。
Promiseを返すと、jestはPromiseが解決されるまで待機します。
つまり、setImmediate
が終わった後にexpect(text).toBe("fuga")
が実行されているということになります。
なぜ、setImmediateなのか
jestはNode.jsで動作しています。
Node.jsのイベントループでは、setImmediate
が最後に実行されます。
Node.jsのイベントループについてはこちらを参照
https://blog.hiroppy.me/entry/nodejs-event-loop