お知らせ
現在サイトのリニューアル作業中のため、表示が崩れているページが存在することがあります。
Jestで無限ループ処理をテストするときにループから抜けられなくて困ったのでメモ。
参考までにこの記事ではイベントループのように脱出手段のある無限ループを想定しています。
| Env | Ver |
|---|---|
| @types/jest | 29.5.7 |
| jest | 29.7.0 |
| typescript | 5.2.2 |
import { getHandle } from './lib/get-handle';
export const main = () => {
for (;;) {
const handle = getHandle();
if (handle === 'Click') {
console.log('click');
} else if (handle === 'KeyDown') {
console.log('keydown');
} else {
break;
}
}
};
.mockReturnValue()ではなく.mockReturnValueOnce()を使うのが肝です。
.mockReturnValue()だと同じ値が毎回返るので無限ループから抜けられませんが、.mockReturnValueOnce()は一回だけなので抜けられます。チェーンすると二回目、三回目の返り値も設定できます。
なお、以下の例では.mockReturnValueOnce()をチェーンさせていますが、させなくてもテストとしては正常に動作します。指定がない場合はundefinedが返るようです。(基本的には明示的に指定しておいた方が良いと考えています。
import { main } from '.';
import * as getHndl from './lib/get-handle';
jest.mock('./lib/get-handle');
describe('main', () => {
it('Clickイベントの分岐に入ること', () => {
jest
.spyOn(getHndl, 'getHandle')
.mockReturnValueOnce('Click')
.mockReturnValueOnce('');
const spiedConsoleLog = jest.spyOn(console, 'log');
main();
expect(spiedConsoleLog).toHaveBeenCalledWith('click');
});
});
.toHaveBeenCalledWith()は.toEqual()と同じロジックで判定しているらしいので、.toStrictEqual()版もあると便利な気がしました。気が向いたらPR出してみようかな…。