jestの使い方でかなり詰まっていた箇所のメモです。jestのバージョンは23です。
同一ファイルに複数のexportがありかつ一つがWrapperとしているような構成のモジュールをテストしたい場合のお話。
例えば
exModule
export const hoge = () => {
console.log('huga');
}
export const fuga = () => {
hoge();
}
というようなモジュールをテストする場合、hoge
がコールされるかテストするため 下記のようなモックを作ってみてテストしてみた。
mocks/exModule
export const hoge = jest.fn();
export const fuga = requre.requireActual('../exModule')
テスト(所々省いて書いてます)
import * as module from 'exModule'l;
jest.mock('exModule');
module.fuga();
expect(module.hoge).toBeCalled(); //通ることを期待
module.hogeが呼ばれない。どうも同じファイルでexportされているものはモックされないらしい。
だいぶ長い間悩んだ結果、以下の方法にたどり着いた。
https://stackoverflow.com/questions/45111198/how-to-mock-functions-in-the-same-module-using-jest
mockを作らず jest.spyOn
を使う、だと!
先のモックのコードは捨てて、以下のようにテスト書き直し。
const mockHoge = jest.spyOn(module, 'hoge');
module.fuga()
expect(mockHoge).toBeCalled();
しかし、これだけではダメだった。。。
いろいろ試した結果、元のコードを以下のようにしたら通った。
export const hoge = () => {
console.log('huga');
}
export const fuga = () => {
exports.hoge();
}
exports
をつけて明示的にしたところ動きました。
結構トリッキーにテストを書かざる得ないのが辛いです。でも結構クリティカルな事案だし、そもそも「ファイル構成構造変えろよ」というのがもっともな意見。jestはall in oneなテストフレームワークなので便利な方だなと。フロントエンドでもテスト大事!