しおしお

IntelliJ IDEAのことなんかを書いてます

jest-whenを試してみたよ

Vue.jsのコンポーネントテストをjestを使ってやっている中で、モック用のライブラリのjest-whenを知ったので軽くお試ししてみたよ。

jest-whenとは

ざっくりこんなことが出来るようです。

  • パラメータの内容に応じて、モックが返す値を簡単に定義できる
  • Promiseを返すケースをちょっとだけ簡単に書ける

インストール

npm使って、さくっとインストールですね。

npm i --save-dev jest-when

お試ししてみる

モック化したい関数を定義する

引数を2つ受け取る関数ですね。モック化して動かすので中身はなくても大丈夫ですが…

export default function test(n1, n2) {
  return n1 + n2
}

モック化してテストするコード

  • この例の場合、calledWith1, 2を指定しているので、test(1, 2)と呼び出した場合に100を返すモックが定義される
    もし、パラメータが1, 2以外の場合は、undefinedが戻される
  • モックが返す値の定義は、mockReturnValueOnceで行っているため、1回だけ100を返す
    もし、2回以上呼び出された場合は、2回目以降はundefinedが戻される
import test from './test'
import {verifyAllWhenMocksCalled, when} from 'jest-when'
jest.mock('./test.js')

describe('test', () => {

  it('jest-when', () => {
    when(test)
      .calledWith(1, 2)
      .mockReturnValueOnce(100)

    expect(test(1, 2)).toBe(100)

    verifyAllWhenMocksCalled()
  })
})

jest-whenを使わなかった場合のテストコードはこんな感じですね。 パラメータの検証を後からやらないといけないのでちょっと面倒ですね。

  it('test', () => {
    test
      .mockReturnValueOnce(100)

    expect(test(1, 2)).toBe(100)
    expect(test.mock.calls[0]).toEqual([1, 2])
  })

実行結果

テストが成功しました(๑•̀ㅂ•́)و✧

npx jest test.spec.js
 PASS test.spec.js
  test
    ✓ jest-when (3ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.378s
Ran all test suites matching /test.spec.js/i.

試しに異なるパラメータに書き換えてテストを実行してみる

パラメータの値を変更してみます。

@@ -9,7 +9,7 @@
       .calledWith(1, 2)
       .mockReturnValueOnce(100)
 
-    expect(test(1, 2)).toBe(100)
+    expect(test(1, 3)).toBe(100)
 
     verifyAllWhenMocksCalled()
   })

モック定義時と実際の呼び出し時のパラメータが違うので、undefinedが戻されてテストが失敗しますね。

npx jest test.spec.js
 FAIL  test.spec.js
  test
    ✕ jest-when (6ms)test › jest-when

    expect(received).toBe(expected) // Object.is equality

    Expected: 100
    Received: undefined

      10 |       .mockReturnValueOnce(100)
      11 | 
    > 12 |     expect(test(1, 3)).toBe(100)
         |                        ^
      13 | 
      14 |     verifyAllWhenMocksCalled()
      15 |   })

      at Object.<anonymous> (test.spec.js:12:24)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.45s
Ran all test suites matching /test.spec.js/i.

Promiseを返すようなケースを試してみる

  • Promiseを返す場合は、戻り値の定義時にmockResolvedValueOnceを使ってあげる
  • rejectを返す場合には、mockRejectedValueOnceを使ってあげる
  it('jest-when', () => {
    when(test)
      .calledWith(1, 2)
      .mockResolvedValueOnce(100)

    expect(test(1, 2)).resolves.toBe(100)

    verifyAllWhenMocksCalled()
  })

実行結果

よさげに動きますね(๑•̀ㅂ•́)و✧

npx jest test.spec.js
 PASS  test.spec.js
  test
    ✓ jest-when (4ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.322s
Ran all test suites matching /test.spec.js/i.

まとめ

jest-whenを使うと、パラメータ毎の結果の定義が出来るので、使わなかった場合と比べてちょっとだけ簡単にモックの定義と検証が出来るかも