はじめに
TypeScript で Jest のモック機能を使おうとしたら、ハマりました。。。
解決方法を見つけたのでメモします。
対象読者
- TypeScript の知識をある程度持っている
- Jest を TypeScript で実行できる環境がある
環境
- node.js, 8.10.x
- typescript, 3.2.x
- axios, 0.18.x
- jest, 23.6.x
- ts-jest, 23.10.x
- macOS X El Capitan
テスト対象
ソース
src/index.ts
import axios from 'axios';
export async function main() {
try {
const { data } = await axios.get('{YOUR-API-ENDPOINT}');
return data; // { message: "Real response!" }
} catch (err) {
throw new Error(err.message);
}
}
main().then(res => console.log(res));
実行結果
$ npx tsc
$ node dist/index.js
{ message: 'Real response!' }
テストコード
書き方1
test/index.test.ts
jest.mock('axios');
import axios from 'axios';
// tslint:disable-next-line:no-any
(axios.get as any).mockResolvedValue({ data: { message: 'Mock response!!!' } });
import { main } from '../src/index';
describe('main test', () => {
it('axios return mock value', async () => {
const res = await main();
expect(res.message).toBe('Mock response!!!');
});
});
書き方2
test/index.test.ts
jest.mock('axios');
import axios, { AxiosInstance } from 'axios';
// tslint:disable-next-line:no-any
const myAxios: jest.Mocked<AxiosInstance> = axios as any;
myAxios.get.mockResolvedValue({ data: { message: 'Mock response!!!' } });
import { main } from '../src/index';
describe('main test', () => {
it('axios return mock value', async () => {
const res = await main();
expect(res.message).toBe('Mock response!!!');
});
});
テスト実行結果
おわりに
書き方の 1 と 2 を比較した場合、文字数が少なくなるのは 1 ですが、2 の場合は上の例で言うとmyAxios
に型を指定しているためIDEの補完が効くようなるというメリットがあります。
1 の場合は mockResolvedValue()
を手動で書き込む必要がありますが、2 の場合はIDEの予測で出てきます。
コーディングミスを減らすためにも自分は 2 を使っていこうかなと思っています。
any型を使わずに書ける方法が知りたい。。。
2019/07/23 追記
@Statham さんにコメントにて any 型を使わない書き方を教えていただきました!ありがとうございます!