いたずらとモンク


単位テストを書くとき、あなたはしばしばいくつかの機能を模擬しなければなりません.あなたのテストを決定的にするか、特定の関数が呼ばれると主張することができます.あなたの関数がフェッチを使用して正しいAPIを呼び出すことを評価しようとしているとしましょう.
async function getUser(id) {
  return fetch(`/users/${id}`)
}
これを主張しようとするとき、我々が持っている異なるオプションを見ましょう.

Jestの使用FN
それを達成する最初の方法はjest.fn とfetch関数を置き換える.
describe('my test', () => {
  it('calls the right route', async () => {
    // Create an empty mock function which just returns nothing
    const mockedFetch = jest.fn()
    // Set the global fetch to be this function
    global.fetch = mockedFetch
    await getUser(id)
    expect(mockedFetch).toHaveBeenCalledWith('/users/12')
  })
}
これはうまくいきますが、いくつか欠点があります.最も大きいのは、手動で実際のフェッチメソッドを参照しておく必要があり、テストの後にその場所に戻します.これが失敗するならば、あなたはテストスイートで他のすべてのテストに影響を及ぼします.
こうすることができます.
describe('my test', () => {
  const realFetch = global.fetch
  beforeAll(() => {
    global.fetch = jest.fn()
  })

  afterAll(() => {
    global.fetch = realFetch
  })
}

Jestの使用スプーン
この場合のより良いアプローチはスパイを使用することです.スパイは、モック機能のすべての機能を持っていますが、より多くの柔軟性を残します.さらに重要なことは、冗談はあなたのためのモックのクリーニングを処理します.以下はSPIESを使ったテストのことです.
describe('my test', () => {
  it('calls the right route', async () => {
    jest.spyOn(global, 'fetch')
    await getUser(id)
    expect(global.fetch).toHaveBeenCalledWith('/users/12')
  })
}
スパイについては2つのことがあります.
  • あなたはまだ使用してテストの間の模擬を忘れて冗談を伝える必要がありますmockClear , mockReset or mockRestore (後に)
  • デフォルトでは、関数は単にスパイされ、元のコードが実行されないようにします.
  • これらの2つの動作を修正したい場合は、次のようになります.
    describe('my test', () => {
      beforeEach(() => {
        jest.restoreAllMocks()
      })
    
      it('calls the right route', async () => {
        jest.spyOn(global, 'fetch').mockReturnValue({})
        await getUser(id)
        expect(global.fetch).toHaveBeenCalledWith('/users/12')
      })
    }
    
    ここでは、取得する実際の呼び出しを防ぐmockReturnValue ( mockImplementation また、すべてのテストを実行する前に、初期状態にすべての既存の模擬を復元します.

    クリア、リセット、復元
    mockをクリアするときには、以下の3つの関数を呼び出します.
  • mockClear - モックをクリアすることは、モックに既に格納された呼び出しの履歴をクリアすることを意味します.あなたがテストのいくつかのポイントの後に呼び出しを数え始めるならば、それは役に立ちます.
  • mockReset - ちょうどあなたが呼んだならば、mockを取り戻すことは新鮮な状態に模擬を返しますspyOn 関数に.すべてのmockked実装または戻り値は忘れられます.もちろんそれはすべてを意味するmockClear 意味する.
  • mockRestore - 関数を復元すると、実際にはモックを削除し、元の実装を復元します.
  • これらの関数は二つの異なる方法で使用できます:
  • mockked関数に直接myMockedFunction.mockClear
  • 作成したすべてのmockに影響を与えるようにグローバルにjest. clearAllMocks()

  • Jestの使用模擬
    Jestでモッキングするもう一つのアプローチは、使用ですjest.mock . それは完全にモジュールを模擬することができます.例えば:
    // Here I am mocking the 'os' module entirely
    // It now only exposes one function: hostname
    // Which always returns 'my-computer'
    jest.mock('os', () => {
      return { hostname: () => 'my-computer' }
    })
    
    ご覧のように、2番目のパラメータを使用して、インポートを返します.モジュールをインポートしない場合は、空のオブジェクトを返します.
    また、このファクトリを特定のファイルに書き込むこともできます.例えばファイルをインポートする場合src/my-module.js , そして、すべてのテストでは、特定の工場をしたいファイルを作成することができます名前src/__mocks__/my-module.js . このファイルが何をエクスポートしたら、何をインポートするのかjest.mock('src/my-module') 工場なしで提供されます.

    では、今何を使いますか.
    できるだけ多くの人と一緒に行きましょうspyOn バージョン.
    使用jest.fn 関数にmockked callbackを渡す場合には、いくつかのユースケースを直接持っています.jest.mock が強力ですが、私は主に特定のモジュールをロードするのを防ぐために使用します.私はまた、外部モジュールから多くの機能を一度に模擬する必要があるときに使用します.
    写真でTobias Tullius on Unsplash