2
4

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.

Vue.jsでaxiosをモック化してテストする!2

Posted at

axios.createで作成したaxiosのラッパーを使ってテストする方法です。
もっと良いやり方があるよ!という場合はコメントいただけると幸いです。
ひとまずこれでテストはできます。モダンなやり方かはわかりませんのであしからず。

必要なライブラリ

  • axios-mock-adapter
  • vueのjestライブラリ達

テストコード

axiosのラッパーをインポート

import { axiosWrapper } from "@/domain/axios"

@/domain/axiosでは、axiosWrapperをexportしています。

import axios from "axios"
export const axiosWrapper = axios.create({
  baseURL: xxx,
  timeout: 15000
  ...
})

axiosラッパーをモック化

axios-mock-adapterを利用して、ラッパーをモック化します。

const mockAxios = new MockAdapter(axiosWrapper)

モックの振る舞いを設定

getの場合

it("テストケース: get", async () => {
  mockAxios.onGet(URL).reply(200, {})
  ...
})

URLの部分は、axios.createでbaseURLを設定していれば、baseURL以降のURLでOKです。
baseURLを設定していなければ、httpから始まるAPIのURLを指定する必要があるかと思います。

postの場合

it("テストケース: post", async () => {
  mockAxios.onPost(URL).reply(200, {})
  ...
})

2本分のAPIをモック化する場合

同じ関数内で2本のAPIを呼んでいる場合等、2本分のAPIの戻り値を指定したい場合は、onXxxとreplyを繰り返します。

it("テストケース: API2本呼び出し", async () => {
  mockAxios
    .onGet(URL1).reply(200, {})
    .onGet(URL2).reply(200, {})
  ...
})

同じAPIを呼び出し、1回目と2回目で戻り値を変えたい場合も同じやり方が使えます。その場合はreplyOnceを使うと良いです。

it("テストケース: 同じAPI2回呼び出し", async () => {
  mockAxios
    .onGet(URL1).replyOnce(400, {})
    .onGet(URL1).replyOnce(200, {})
  ...
})

タイムアウトやネットワークエラーを戻り値とする

タイムアウトやネットワークエラー時のテストをしたい場合は、replyの部分をtimeoutやnetworkErrorOnceにします。

it("テストケース: タイムアウト", async () => {
  mockAxios
    .onGet(URL).timeout()
  ...
})

it("テストケース: ネットワークエラー", async () => {
  mockAxios
    .onGet(URL).networkErrorOnce()
  ...
})

結果の確認

何回呼ばれた?

history.getが配列になっているため、その配列数で呼ばれた数がわかります。

it("テストケース: API呼び出し回数", async () => {
  mockAxios.onGet(URL).reply(200, {})
  ...
  expect(mockAxios.history.get.length).toBe(2)
})

呼んだ時のリクエストは何か?

history.get[i]でそれぞれ取れます。

it("テストケース: get", async () => {
  mockAxios.onGet(URL).reply(200, {})
  ...
  // header
  expect(mockAxios.history.get[0].header).toEqual({
    token: "xxxxx"
  })
  
  // get parameter
  expect(mockAxios.history.get[0].params).toEqual({
    userId: "xxxxx"
  })
})

it("テストケース: post", async () => {
  mockAxios.onPost(URL).reply(200, {})
  ...
  // header
  expect(mockAxios.history.post[0].header).toEqual({
    token: "xxxxx"
  })
  
  // post body
  expect(JSON.parse(mockAxios.history.post[0].data)).toEqual({
    userId: "xxxxx"
  })
})

リセット

テストケース毎に、終了時にhistoryをリセットします。リセットしないとitを実行するたびにmockAxios.historyに溜まっていきます。

describe("テスト", () => {
  afterEach(() => {
    mockAxios.resetHistory()
  })
})

蛇足

Axiosとは関係ありませんが、関数をモックしたい場合は以下のようにします。

import * as strUtils from "@/utils/strUtils"
jest.spyOn(strUtils, "isNull").mockReturnValue(false)

// promiseのresolveを返す関数の場合
jest.spyOn(strUtils, "isNull").mockResolvedValue("ok")

// promiseのrejectを返す関数の場合
jest.spyOn(strUtils, "isNull").mockRejectedValue("error")

jestのモックを使うときは、リセットを忘れずに。

describe("テスト", () => {
  afterEach(() => {
    jest.clearAllMocks()
  })
})
2
4
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
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?