LoginSignup
4
1

Jestで既存の関数をモック化する方法

Last updated at Posted at 2024-03-03

はじめに

どうもこんにちは!僕は現在1ヵ月本気の技術力向上を目指している現役高校生1年生(@shunii )です!
今回はJestでモック関数を実装する際、理解に躓いたのでまとめます。

モック関数とはなんぞや

モック関数を簡易的に説明すると、

既存の関数の代替

になります。

  • 具体的な使用例
    外部APIとの通信を行う関数をモック化すれば、実際には通信を行うことなく意図したテストを実行することができるようになります。

これって結構うれしいですよね。

関数をモック化する流れ

  1. jest.mockをトップレベルで呼ぶ
    jest.mockを呼び出すことで、既存の関数をモック化することが出来ます。この時点ではモック関数の具体的な処理は定義されておらず、undefinedを返す仕様になっています。
    jest.mock("モック化したい関数があるファイルのパス")
    

そして必ずjest.mockはファイルのトップレベル(describeの外)に書きましょう!!!
細かい話をするとjest.mockはどこで書いても自動的にトップレベルに記載されたのと同じようにする(いわゆる巻き上げ・ホイスティングをする)のですが、エラーが出てしまう場合はまずこれを疑ってみてください。可読性を考慮してもトップレベルに書くことが推奨であるとドキュメントにも記載されています。

手順2はAとBの2つのパターンを書きます
2. Aパターン: jest.mockの中で関数を定義する
手順1で書いたjest.mockのなかで関数を実際に定義していきます。mockImplemetationを使うことでモック関数の中身を定義できます。

jest.mock('ファイルパス', () => ({
  //functionNameに実際の関数の名前を書く
  functionName: jest.fn().mockImplementation(() => 'mocked value'),
}));

これで、mocked valueという文字列を返却するモック関数が出来上がりました!

イメージ( 以下の考え方だとわかりやすいかも )

  • jest.mockは「関数をモック化するよ!」という宣言的な感じ。実際には中身はない( => undefined )
  • jest.fnは「実際に疑似的な関数を作るよ!」って感じ。中身をちゃんと作ってあげよう

他にもモック関数の作り方はあります。僕が調べたものを以下に示します。使いやすいものを選んでみてください!詳細はぜひ公式ドキュメントを確認してみてください。

  • mockReturnValue: モック関数の戻り値だけを指定できます
    jest.mock('module_name', () => ({
      functionName: jest.fn().mockReturnValue('mocked value'),
    }));
    

  • mockResolvedValue: Promiseを返却したい( 非同期関数 )の場合に使いやすいです。外部APIとの通信する関数とかで使えそうです
    jest.mock('module_name', () => ({
      functionName: jest.fn().mockResolvedValue('mocked value'),
    }));
    

2. Bパターン: モック関数をdescribeの中で定義する
まず、ファイルのトップレベルで以下のように記述します。jest.fnで関数を作っておきます。

jest.mock('ファイルパス', () => {
    return {
        functionName: jest.fn()
    }
})

そして、describeの中で以下のようにモック関数を定義します。

describe('テストの名前', () => {
    beforeEach(() => {
        //ここのfunctioName.~の書き方はAパターンで示したように自由です。
        functionName.mockImplementation(() => 'mocked')
    })
})

難しく見えるかもしれませんが、Aパターンでやっていることを切り離しているだけ、と考ることができればわりと理解しやすいと思います。

beforEachとは
beforeEachを使うことで、各テストケースが実行される前にある処理を実行することが出来ます。これを使っておかないと初期化でエラーを吐かれます。
( initiallizeみたいな単語がエラーにあったらこれを疑ってみてください )

Bパターンの利点としては、

describe(各テストのグループ)ごとにモック関数の仕様を変更することが出来る点

です。僕はまだそれを利点と感じる場面に出くわしたことはないですが、個人的に可読性の面で好みです。モック化の宣言と定義がわかれている感じがいいです。

終わりに

今回の内容を理解するのに結構な時間がかかったので、どなたかの参考になれば幸いです!意味わかんないーとおもったら公式ドキュメントをぜひ頑張って読んでみてください。
いいねとコメント大歓迎です!

About Me

  • X(Twitter)

参考

4
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
4
1