test
TypeScript
Mock
jest
axios

TypeScript × Jest で axios のモックを作りテストを実施する


はじめに

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!' }

スクリーンショット 2018-12-05 0.06.35.png


テストコード


書き方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!!!');
});
});



テスト実行結果

スクリーンショット 2018-12-05 0.05.46.png


おわりに

書き方の 1 と 2 を比較した場合、文字数が少なくなるのは 1 ですが、2 の場合は上の例で言うとmyAxiosに型を指定しているためIDEの補完が効くようなるというメリットがあります。

1 の場合は mockResolvedValue() を手動で書き込む必要がありますが、2 の場合はIDEの予測で出てきます。

コーディングミスを減らすためにも自分は 2 を使っていこうかなと思っています。

any型を使わずに書ける方法が知りたい。。。