LoginSignup
0
1

More than 1 year has passed since last update.

Jestのjest.fn()とjest.spyOn()関数について

Posted at

mockingとは

単独テストコードを作成する際、該当のコードが依存する部分を偽の動きをするもの(mock)に変更すること。テスト対象のコードが依存する部分を直接作成することが難しい場合mockingする。

jest.fn()の使用方法

jestでは偽の関数を作成するjest.fn()関数を提供している。

javascript
const mockFn = jest.fn()

この偽の関数は引数をもって呼び出すことも可能である。

javascript
mockFn()
mockFn(1)
mockFn("a")
mockFn([1, 2], { a: "b" })

しかしこのままだと、偽の関数は何も設定してないためundefinedをreturnする。
mockReturnValue(return値)を利用して偽の関数がどの値をreturnすべきかを設定することができる。

javascript
mockFn.mockReturnValue("I am a mock!")
console.log(mockFn()) // I am a mock!

非同期処理をする偽の関数を作りたればmockResolvedValue(return値)を利用することができる。

javascript
mockFn.mockResolvedValue("I will be a mock!")
mockFn().then((result) => {
  console.log(result) // I will be a mock!
})

最後に、mockImplementation(コールバック関数)を利用すると、モックを丸ごと再構成することもできる。

javascript
mockFn.mockImplementation((name) => `I am ${name}!`)
console.log(mockFn("John")) // I am John!

これらの偽の関数は、何回呼び出されて、どんな引数が与えられたかを検証することができる。

javascript
mockFn("a")
mockFn(["b", "c"])

expect(mockFn).toBeCalledTimes(2)
expect(mockFn).toBeCalledWith("a")
expect(mockFn).toBeCalledWith(["b", "c"])

jest.spyOn()の使用方法

あるオプジェクトの中にある関数をmock化せず、該当の関数が呼び出されたか、どのように呼び出されたかを監視する方法。jest.spyOn(object, methodName)を利用することで監視する。

javascript
const calculator = {
  add: (a, b) => a + b,
}

const spyFn = jest.spyOn(calculator, "add")

const result = calculator.add(2, 3)

expect(spyFn).toBeCalledTimes(1)
expect(spyFn).toBeCalledWith(2, 3)
expect(result).toBe(5)

テスト

ここでは以下のような非同期処理をするfindOne()というメソッドをテストする。

javascript
const axios = require("axios")
const API_ENDPOINT = "https://***.***.com"

module.exports = {
  findOne(id) {
    return axios
      .get(`${API_ENDPOINT}/users/${id}`)
      .then((response) => response.data)
  },
}

やり方としては以下の方法にする。

  • テストコードでaxiosをインポートする。
  • axiosのget関数がnetworkの影響を受けないようにモックかする。
  • つまり、いつも同じ値を返す関数に変更する。

以上の方法でテストコードを書くと以下の通りである。

javascript
const axios = require("axios")
const userService = require("./userService")

test("findOne returns what axios get returns", async () => {
  axios.get = jest.fn().mockResolvedValue({
    data: {
      id: 1,
      name: "John",
    },
  }) // axiosのgetメソッドを非同期でいつも成功する値を返すモック関数にする。

  const user = await userService.findOne(1)
  expect(user).toHaveProperty("id", 1)
  expect(user).toHaveProperty("name", "John")
})
0
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
0
1