5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vitestでaxiosをモックする方法(mock, spyOn)

Posted at

はじめに

axiosのようなHTTPリクエストを含む関数をテストする場合、テストの度にHTTPリクエストを行うと時間がかかったりサーバーに負荷がかかります。そのようなHTTPリクエストをモックすることで外部へのアクセスをすることなく、高速でテストが行えるようになります。

VitestではmockまたはspyOn関数で特定のメソッドをモックできます。mockはモジュール全体をモック、spyOnは特定のオブジェクトのメソッドをモックという違いはありますが、どちらでもモックできます。詳細を知りたい方は以下が参考になると思います。

モックする方法

ユーザー取得とユーザー作成をする関数です。これらで使用しているaxiosをモックします。

src/fetchers.ts
import axios from 'axios'

// ユーザーを取得する関数
export const fetchUsers = async () => {
  return axios.get('/users').then((res) => res.data)
}

// ユーザーを作成する関数
export const createUser = async (user: { name: string }) => {
  return axios.post('/users', user).then((res) => res.data)
}

mockを使用した場合

vi.mock('axios')でaxiosをモックします。axios.get()は非同期関数のためmockResolvedValueで返り値を指定します。

src/mock.test.ts
import { it, vi, expect, beforeEach } from 'vitest'
import type { Mocked } from 'vitest'
import axios from 'axios'
import type { AxiosStatic } from 'axios'

import { fetchUsers, createUser } from './fetchers'

// axiosをモック
vi.mock('axios')

beforeEach(() => {
  // モックをリセット
  vi.resetAllMocks()
})

it('ユーザー取得のモック', async () => {
  const mockData = [
    { id: 1, name: 'tarosuke' },
    { id: 2, name: 'momo' },
  ]

  const mockedAxios = axios as Mocked<AxiosStatic>

  // axiosのgetの返り値を指定
  mockedAxios.get.mockResolvedValue({ data: mockData })

  const users = await fetchUsers()

  // 実行の引数を検証
  expect(axios.get).toBeCalledWith('/users')

  // 取得した値が同じか検証
  expect(users).toEqual(mockData)
})

it('ユーザー作成のモック', async () => {
  const mockData = { name: 'pac' }

  const mockedAxios = axios as Mocked<AxiosStatic>

  // axiosのpostの返り値を指定
  mockedAxios.post.mockResolvedValue({ data: mockData })

  const user = await createUser(mockData)

  // 実行の引数を検証
  expect(axios.post).toBeCalledWith('/users', mockData)

  // 取得した値が同じか検証
  expect(user).toEqual(mockData)
})

spyOnを使用した場合

vi.spyOn(axios, 'get')でaxiosのgetをモックします。axios.get()は非同期関数のため、こちらも同じくmockResolvedValueで返り値を指定します。

src/spyOn.test.ts
import { it, vi, expect, beforeEach } from 'vitest'
import axios from 'axios'

import { fetchUsers, createUser } from './fetchers'

beforeEach(() => {
  // モックをリセット
  vi.resetAllMocks()
})

it('ユーザー取得のモック', async () => {
  const mockData = [
    { id: 1, name: 'tarosuke' },
    { id: 2, name: 'momo' },
  ]

  // axiosのgetの返り値を指定
  vi.spyOn(axios, 'get').mockResolvedValue({ data: mockData })

  const users = await fetchUsers()

  // 実行の引数を検証
  expect(axios.get).toBeCalledWith('/users')

  // 取得した値が同じか検証
  expect(users).toEqual(mockData)
})

it('ユーザー作成のモック', async () => {
  const mockData = { name: 'pac' }

  // axiosのpostの返り値を指定
  vi.spyOn(axios, 'post').mockResolvedValue({ data: mockData })

  const user = await createUser(mockData)

  // 実行の引数を検証
  expect(axios.post).toBeCalledWith('/users', mockData)

  // 取得した値が同じか検証
  expect(user).toEqual(mockData)
})

まとめ

Vitestでaxiosをモックする方法をご紹介しました。mockとspyOnのどちらでもモックできますが、個人的にはspyOnの方がコード量が少なく済むため好みです。

最後に

GoQSystemでは一緒に働いてくれる仲間を募集中です!

ご興味がある方は以下リンクよりご確認ください。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?