Jestで外部モジュールをモックする場合、jest.mock()
メソッドを使用してモジュールの関数を自動モックできます。
その後、必要に応じて、モックされたモジュール上のモックされた関数を操作および調査できます。
たとえば、axiosモジュールをモックするための次の不自然な例を考えてみましょう。
_import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';
jest.mock('axios');
it('Calls the GET method as expected', async () => {
const expectedResult: string = 'result';
axios.get.mockReturnValueOnce({ data: expectedResult });
const result = await myModuleThatCallsAxios.makeGetRequest();
expect(axios.get).toHaveBeenCalled();
expect(result).toBe(expectedResult);
});
_
上記はJestで正常に実行されますが、TypeScriptエラーがスローされます。
プロパティ 'mockReturnValueOnce'はタイプ '(url:string、config ?: AxiosRequestConfig | undefined)=> AxiosPromise'に存在しません。
_axios.get
_のtypedefには、当然mockReturnValueOnce
プロパティが含まれていません。 Object(axios.get)
としてラップすることにより、TypeScriptに_axios.get
_をObjectリテラルとして処理させることができますが、
型の安全性を維持しながら関数をモックする慣用的な方法は何ですか?
このコード行を追加const mockedAxios = axios as jest.Mocked<typeof axios>
。そして、mockedAxiosを使用してmockReturnValueOnceを呼び出します。コードでは、次のように実行する必要があります。
import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
it('Calls the GET method as expected', async () => {
const expectedResult: string = 'result';
mockedAxios.get.mockReturnValueOnce({ data: expectedResult });
const result = await myModuleThatCallsAxios.makeGetRequest();
expect(mockedAxios.get).toHaveBeenCalled();
expect(result).toBe(expectedResult);
});
型の安全性を維持しながら関数を慣用的にモックするには、 spyOn と mockReturnValueOnce を組み合わせて使用します。
import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';
it('Calls the GET method as expected', async () => {
const expectedResult: string = 'result';
// set up mock for axios.get
const mock = jest.spyOn(axios, 'get');
mock.mockReturnValueOnce({ data: expectedResult });
const result = await myModuleThatCallsAxios.makeGetRequest();
expect(mock).toHaveBeenCalled();
expect(result).toBe(expectedResult);
// restore axios.get
mock.mockRestore();
});
インポートに新しい機能を提供してdeclare module "axios" { ... }
などの元のモジュールを拡張する通常のアプローチ。モックはあるテストでは利用でき、別のテストでは利用できない場合がありますが、ここでは最適な選択ではありません。
この場合、タイプセーフなアプローチは、必要に応じてタイプをアサートすることです。
(axios.get as jest.Mock).mockReturnValueOnce({ data: expectedResult });
...
expect(axios.get as jest.Mock).toHaveBeenCalled();