JavaScriptJestNode.js

Jest + TypeSciptでaxiosを利用したコードのテスト

いい加減ちゃんと向き合わないと行けないときが来た気がしたので。非同期のモックテストをいろいろと試してみました。 axiosを使ったテスト HTTPリクエストでお世話になるaxiosで試します。 というシンプルなget関数 […]

広告ここから
広告ここまで

いい加減ちゃんと向き合わないと行けないときが来た気がしたので。非同期のモックテストをいろいろと試してみました。

axiosを使ったテスト

HTTPリクエストでお世話になるaxiosで試します。

import axios from 'axios'

export const get = async () => {
  return axios.get('https://wp-kyoto.cdn.rabify.me/wp-json')
}

というシンプルなget関数を用意します。

jest.mockでaxiosをmockする

axiosをjestでモックしてしまいます。mockResolvedValueでレスポンスを作れますが、TypeScriptでエラーがでますのでanyを噛ませます。

import { get } from '../../libs/index'
import axios from 'axios';

jest.mock('axios');
describe('first test', () => {
  afterEach(() => jest.restoreAllMocks())
  it('should return empty string', async () => {
    (axios.get as any).mockResolvedValue('')
    const data = await get()
    expect(data).toEqual('')
  })
})

jest.fnでaxios.getをmockする

若干力技な気もしますが、以下のように書くことでjest.fnを使えます。

import { get } from '../../libs/index'
import axios from 'axios';

describe('first test', () => {
  afterEach(() => jest.restoreAllMocks())
  it('should return empty string', async () => {    
    (axios.get as any) = jest.fn(async () => '')
    const data = await get()
    expect(data).toEqual('')
    expect(axios.get).toHaveBeenCalledTimes(1)
  })
})

こちらだとgetがコールされたかもテストできます。

mockImplementationを使う

mockResolvedValueを使うことで、jest.fnと同じことができる様子です。

import { get } from '../../libs/index'
import axios from 'axios';

jest.mock('axios');
describe('first test', () => {
  afterEach(() => jest.restoreAllMocks())
  it('should return empty string', async () => {
    (axios.get as any).mockImplementation(async () => 42)
    const data = await get()
    expect(data).toEqual(42)
    expect(axios.get).toHaveBeenCalledTimes(1)
  })
})

mockImplementationOnceを使うと、値を変えれる

呼び出す回数によってレスポンスが変わる場合、Onceのほうを使うとよいです。

import { get } from '../../libs/index'
import axios from 'axios';

jest.mock('axios');
describe('first test', () => {
  beforeAll(() => {
    (axios.get as any).mockImplementationOnce(async () => 42)
      .mockImplementationOnce(async () => 24)
  })
  afterAll(() => jest.restoreAllMocks())
  it('should return empty string', async () => {
    const data = await get()
    expect(data).toEqual(42)
    expect(axios.get).toHaveBeenCalledTimes(1)
    const data1 = await get()
    expect(data1).toEqual(24)
    expect(axios.get).toHaveBeenCalledTimes(2)
  })
})

ちなみに定義した以上に呼び出すとmockImplementationの値が返ります。

import { get } from '../../libs/index'
import axios from 'axios';

jest.mock('axios');
describe('first test', () => {
  beforeAll(() => {
    (axios.get as any)
      .mockImplementation(async () => 1)
      .mockImplementationOnce(async () => 42)
      .mockImplementationOnce(async () => 24)
  })
  afterAll(() => jest.restoreAllMocks())
  it('should return empty string', async () => {
    const data = await get()
    expect(data).toEqual(42)
    expect(axios.get).toHaveBeenCalledTimes(1)
    const data1 = await get()
    expect(data1).toEqual(24)
    expect(axios.get).toHaveBeenCalledTimes(2)
    const data2 = await get()
    expect(data2).toEqual(1)
    expect(axios.get).toHaveBeenCalledTimes(3)
    const data3 = await get()
    expect(data3).toEqual(1)
    expect(axios.get).toHaveBeenCalledTimes(4)
  })
})

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts