見出し画像

【Jest_26】 axiosをモックするには?

JestでAxiosをモックするには?

なぜ Axios をモックするのか?

Axios は HTTP 通信を行うためのライブラリです。しかし、テストにおいて実際に API に通信するのはNGです。理由:

  • 本番APIを叩くと予期せぬ副作用が起きる

  • 通信状況によりテストが不安定になる

  • 意図したレスポンスを返せない(テストが書きにくい)

Axiosをモック(擬似化)することで、外部要因のないテストが可能になります。


事前準備

npm install --save-dev jest @types/jest ts-jest
npm install axios
npm install --save-dev @types/axios

1. axiosをモックする基本

テスト対象のコード

// userApi.ts
import axios from 'axios';

export async function getUser(userId: number) {
  const response = await axios.get(`/users/${userId}`);
  return response.data;
}

Jestでaxiosをモックする

方法1: jest.mock('axios') を使う

// userApi.test.ts
import axios from 'axios';
import { getUser } from './userApi';

jest.mock('axios'); // ← axios をモック!

describe('getUser', () => {
  it('should return user data', async () => {
    const mockedAxios = axios as jest.Mocked<typeof axios>;
    const user = { id: 1, name: 'John' };

    mockedAxios.get.mockResolvedValue({ data: user });

    const result = await getUser(1);

    expect(result).toEqual(user);
    expect(mockedAxios.get).toHaveBeenCalledWith('/users/1');
  });
});

2. axiosのレスポンスをもっと自由にカスタム

mockedAxios.get.mockResolvedValueOnce({
  data: { id: 42, name: 'Alice' },
  status: 200,
  headers: {},
});
mockedAxios.get.mockRejectedValueOnce(new Error('404 Not Found'));

3. モックの型安全性を強化したい場合(TypeScript)

const mockedAxios = axios as jest.Mocked<typeof axios>;

これで .get, .post などが型付きで使えます!


4. 共通モック化:mocks/axios.ts を使う

Jestは __mocks__ フォルダにある axios.ts を自動で使う機能があります。

Step1: フォルダ作成とモック定義

// __mocks__/axios.ts
const axiosMock = {
  get: jest.fn(),
  post: jest.fn(),
  put: jest.fn(),
  delete: jest.fn(),
  create: jest.fn(() => axiosMock),
};

export default axiosMock;

Step2: テストファイルで jest.mock('axios')

import axios from 'axios';
jest.mock('axios');

5. axios.create を使ってる場合の注意点

Axiosは axios.create() でカスタムインスタンスを作成できます。

// httpClient.ts
import axios from 'axios';
export const client = axios.create({ baseURL: 'https://api.example.com' });

これを使っている場合、モック方法は少し変わります:

// __mocks__/axios.ts
const instance = {
  get: jest.fn(),
  post: jest.fn(),
  // ...
};

const create = jest.fn(() => instance);

export default {
  create,
};

そしてテストで:

import { client } from './httpClient';
import axios from 'axios';

jest.mock('axios');

test('custom axios client works', async () => {
  const mock = (axios as any).create();
  mock.get.mockResolvedValue({ data: { msg: 'hello' } });

  const result = await client.get('/hello');
  expect(result.data.msg).toBe('hello');
});

6. axiosの呼び出し回数・引数を検証する

expect(axios.get).toHaveBeenCalledTimes(1);
expect(axios.get).toHaveBeenCalledWith('/users/1');

7. axios-mock-adapter(ライブラリ)を使う方法

もっと制御したい場合、公式モックライブラリもあります。

インストール

npm install --save-dev axios-mock-adapter

使い方

import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';

const mock = new MockAdapter(axios);
mock.onGet('/users/1').reply(200, { id: 1, name: 'John' });

test('axios-mock-adapter example', async () => {
  const res = await axios.get('/users/1');
  expect(res.data.name).toBe('John');
});

8. モックと実APIの切り替えを動的にしたいとき

if (process.env.NODE_ENV === 'test') {
  jest.mock('axios');
}

9. よくあるエラーと対処法

axios.get is not a function
 jest.mock('axios') してない
 ちゃんとモック宣言する
Cannot read property 'mockResolvedValue'
 型キャスト忘れ
 as jest.Mocked<typeof axios> を追加
Axios instanceで .get() がundefined
 .create() に対するモック忘れ
 __mocks__/axios.ts を使う or mockCreate() 定義


10. モックのベストプラクティスまとめ

axios全体をモックしたい
 jest.mock('axios') と jest.Mocked<typeof axios>
共通モックを使いたい
 __mocks__/axios.ts
カスタムaxiosを使っている
 create() のモックも書く
レスポンスの種類を細かく制御したい
 axios-mock-adapter
型安全で書きたい
 jest.Mocked<...> を活用


結論

  • JestでのAxiosモックは jest.mock('axios') が基本

  • TypeScriptなら jest.Mocked<typeof axios> を使うと安全

  • __mocks__/axios.ts で共通化もできる

  • より詳細なテストには axios-mock-adapter も便利

  • モックはテスト品質を守る鍵!



いいなと思ったら応援しよう!