高階関数は関数を受け取り、関数を返します。 Jest は、指定した関数が正しく使用されていることを確認する方法を提供します。

高階関数のテスト

メモ化関数を作成するとします。 次のようになります。

// memoize.js
export default function memoize(func) {
  return function (key) {
    const registry = new Map();
    let value = registry.get(key);
    if (typeof value === 'undefined') {
      value = func(key);
      registry.set(key, value);
    }
    return value;
  }
}

そしてそれをテストするには、次のようなものがあります。

import memoize from './memoize';

it('memoizes `func`.', () => {
  // `func` here just cubes the input.
  const func = value => Math.pow(value, 3);
  const memoizedFunc = memoize(func);
  expect(memoizedFunc(3)).toEqual(27);
  expect(memoizedFunc(4)).toEqual(64);
  expect(memoizedFunc(3)).toEqual(27);
  expect(memoizedFunc(5)).toEqual(125);
});

yarn run test、すべてが通過しました、完了ですよね?

高階関数のテストに関する問題

memoizeに問題があることを除いて。 あなたはそれをキャッチしましたか? 問題は、結果の関数をテストしているが、入力関数がどのように使用されているかではないことです。 これを行うために、Jestはモック機能を提供します。

模擬関数の作成

とても簡単です。 実装関数をjest.fnに渡すだけで、モック関数が得られます。

ねえ、それも高階関数です!

これを使用して、memoizeをもう少しよくテストしてみましょう。

import memoize from './memoize';

it('memoizes `func`.', () => {
  // A mock function: a function wrapped in `jest.fn`.
  const func = jest.fn(value => Math.pow(value, 3));
  const memoizedFunc = memoize(func);
  expect(memoizedFunc(3)).toEqual(27);
  expect(memoizedFunc(4)).toEqual(64);
  expect(memoizedFunc(3)).toEqual(27);
  expect(memoizedFunc(5)).toEqual(125);
  // Mock functions have a few special matchers available to them.  Let's take a look.
  // `func` was called.
  expect(func).toHaveBeenCalled();
  // `func` has been called with 5.
  expect(func).toHaveBeenCalledWith(4);
  // `func` was last called with 5.
  expect(func).toHaveBeenLastCalledWith(5);
  // `func` was called thrice (since the second 3 was supposed to be memoized).
  // Supposed to.
  expect(func).toHaveBeenCalledTimes(3);
});

関数の使用方法をテストしているので、memoizeでそのエラーをキャッチできます。