iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

Jestについて調べて見ました!

はじめに!

iimonでエンジニアをしています。奥島です

今回、プロジェクトで Jest を使ってテストを書く機会がありましたが、基本的な実装方法について曖昧な部分があり。復習を兼ねて Jest の基本を整理しました。

基本構文

基本的な3つのメソッドdescribe(ディスクライブ), test, expect(エクスペクト)

1.describeについて

describe関数で、テストのグループ化する事が整理されて見やすくなります。

- 第一引数 : テストブロックの説明(テスト対象メソッドなどを記載)書きます。
- 第二引数 : `test` 関数を使って、実際のテストケースを書きます。

describe('第一引数', () => {
  // 第二引数にテスト関数を使ってテストを定義
});

2.testについて

test 関数を使用してテストを書いていきます。

- 第一引数 : テストケースの説明文を書きます。
- 第二引数 : にテストの内容を書きます。

describe("テストしたいメソッド", () => {
  test("第一引数", () => {
    // 第二引数にテスト内容を定義
  });
});

3.expectについて

expect関数でテスト結果を検証するために使うメソッドです。

expect関数の引数にテスト結果入れてその値が期待通りであるかを確認するための  **マッチャー** 関数で評価します。

//expect(処理内容).toBe(マッチする値);
expect(2 + 3).toBe(5);

マッチャー関数について!

マッチャーは、テストの結果が期待通りであるかどうかを検証します。 Jest では、expect() と組み合わせて使い、さまざまな条件に一致するかを確認する為に使用します。

toBeは値と型が完全に一致していることを確認するためのマッチャー

  • toBe の基本的な使い方
    • 期待値と実際の値が厳密に一致を確認します。
test("数値の比較", () => {
  // OK
  expect(5).toBe(5); //  5 === 5   型の値が同じなのでOK
});

  // NG
  expect(5).toBe(3); //  5 === 3   型は同じだが、値が異なるのでNG
  expect(5).toBe("5"); //  5 === '5' 型が異なるのでNG

test("文字列の比較", () => {
  // OK
  expect("hello").toBe("hello"); // 'hello' === 'hello' 型と値が同じなのでOK

});

  // NG
  expect("hello").toBe("world"); // 'hello' === 'world' 型が同じだが、値が異なるのでNG
  expect("HELLO").toBe("hello"); // 'HELLO' === 'hello' 型が同じだが、大文字小文字が違うのでNG

toEqualは、オブジェクトや配列を比較する際確認するためのマッチャー

  • toEqual の基本的な使い方
    • 配列やオブジェクトの内容を比較する際に使用します。

配列の比較

// OKパターン
test('配列の比較', () => {
  const arr1 = [1, 2, 3];
  const arr2 = [1, 2, 3];
  
  expect(arr1).toEqual(arr2);  // 配列の内容が同じなのでOK
});

// NGパターン
test('配列の要素が異なる', () => {
  const arr1 = [1, 2, 3];
  const arr2 = [1, 2, 4];  // 3 と 4 が異なる

  expect(arr1).toEqual(arr2);  // 配列の要素が異なるのNG
});

// NGパターン
test('配列の順番が異なる', () => {
  const arr1 = [1, 2, 3];
  const arr2 = [3, 2, 1];  // 順番が異なる

  expect(arr1).toEqual(arr2);  // 配列の順番が異なるのでNG
});

// NGパターン
test('配列の長さが異なる', () => {
  const arr1 = [1, 2, 3];
  const arr2 = [1, 2];  // 長さが異なる

  expect(arr1).toEqual(arr2);  // 配列の長さが異なるのでNG
});

// NGパターン
test('異なる型の要素を含む配列', () => {
  const arr1 = [1, 2, 3];   //  2 : 数値
  const arr2 = [1, '2', 3];  //  2 : 文字列

  expect(arr1).toEqual(arr2);  // 型が異なるのでNG
});

// NGパターン
test('undefined と null の比較', () => {
  const arr1 = [1, undefined, 3];  // undefined
  const arr2 = [1, null, 3];       // null

  expect(arr1).toEqual(arr2);  // undefined と null は異なるのでNG
});

オブジェクトの比較

// OKパターン
test('オブジェクトの比較', () => {
  const obj1 = { name: 'Alice', age: 25 };
  const obj2 = { name: 'Alice', age: 25 };
  
  expect(obj1).toEqual(obj2);  // オブジェクトの内容が同じなのでOK
});

// NGパターン(プロパティが異なる場合)
test('異なるプロパティを持つオブジェクト', () => {
  const obj1 = { name: 'Alice', age: 25 }; //  'city' プロパティがない
  const obj2 = { name: 'Alice', age: 25, city: 'Tokyo' }; //  'city' プロパティがある
  
  expect(obj1).toEqual(obj2);  // プロパティの数が異なるのでNG
});

Undefinedの評価をするマッチャー関数

  • toBeUndefined の基本的な使い方
    • toBeUndefinedは値が undefined であるかどうかを確認するために使用します。toBeUndefined は厳密に undefined かどうかをチェックするため、null や他の値は undefinedと一致しません。なのでテストは失敗します。
 // OKパターン
 test('変数がundefinedであることを確認', () => {
  let value;
  expect(value).toBeUndefined();  // valueはundefinedなのでOK
});

// OKパターン
test('直接undefinedと比較する', () => {
  const value = undefined;
  expect(value).toBeUndefined();  // valueはundefinedなのでOK
});

// NGパターン
test('undefinedではない場合', () => {
  const value = 5;
  expect(value).toBeUndefined();  // valueは 5 でundefinedではないのでNG
});

// NGパターン
test('valueがnullの場合', () => {
  const value = null;
  expect(value).toBeUndefined();  // valueはnullでundefinedではないのでNG
});

toHaveBeenCalled(Jest の マッチャーです)

モック関数やスパイ関数が 少なくとも1回は呼び出された かどうかをテストするために使用します

expect(mockFunction).toHaveBeenCalled(); 
// 成功 : モック関数が  1回以上 呼び出された場合にテストが成功します。
// 失敗 : モック関数が 一度も呼ばれていない場合にテストが失敗します。

toHaveBeenCalledTimes(Jest の マッチャーです)

toHaveBeenCalledTimes()は、モック関数が指定した回数だけ呼ばれたかどうかを検証するためのマッチャーです。テストの中で、関数が何回呼ばれたかを確認したい場合に使用します。

mockReturnValue(Jest の マッチャーです)

mockReturnValue()は、モック関数が呼ばれた際に返す値を指定するためのメソッドです。モック関数が呼ばれた際に毎回同じ値を返すように設定できます。

モック関数について

モック関数(mock function)は、テストにおいて特定の関数を模倣(モック)するために使用される関数です。モック関数は、本来の関数を使う代わりに、テスト中にその関数の動作をシミュレートするために使います。

  • jest.fn() の基本的な使い方

jest.fn()は、Jestのモック機能の一部として、関数を模倣(モック)するために使用されます。これにより、元々の関数の挙動をmockReturnValue() を使って制御し、テストの中で関数の動作やtoHaveBeenCalledTimes() などで呼び出し回数、引数、などを簡単に確認できます。

export const sum = (sum:any) => {
    // sumを最初に1回呼び出し
    const result1 = sum();
    console.log(`1回目の結果: ${result1}`);
  
    // sumを2回目に呼び出し
    const result2 = sum();
    console.log(`2回目の結果: ${result2}`);
  
    return { result1, result2 };
};
test('関数が2回呼ばれ、それぞれの結果を返すことを確認', () => {
  //1.モック関数の作成:
  const mockFunction = jest.fn().mockReturnValue(8); 
  // jest.fn()でモック関数を作成し、mockReturnValue(8)を使って返り値を8に設定しています。
  // このモック関数は、呼ばれるたびに8を返します。

  //2. sumにモック関数を渡して実行
  const results = sum(mockFunction);
 
  // mockFunctionが2回呼ばれたことを確認
  expect(mockFunction).toHaveBeenCalledTimes(2);
  // sum(mockFunction)を呼び出し、モック関数が2回呼ばれることを確認します。

  // mockFunctionが最初に8を返し、2回目も8を返すことを確認
  expect(results.result1).toBe(8);
  expect(results.result2).toBe(8);

});

【まとめ】

今回は、Jestの基本的な構文や、テストで使うメソッドやマッチャー関数について学びました。また、モック関数である jest.fn() についても、改めて理解を深めることができました。次回は、spyOn や jest.mock() について学び、さらにJestの活用方法を広げていきたいと思います。


ここまで読んでくださり、ありがとうございます!✨

この記事を読んで少しでも興味を持ってくださった方は、ぜひカジュアル面談でお話ししましょう!

iimon採用サイト / Wantedly / Green

参考

  1. 【理論】Jest 1 テストにおける基本メソッド|【Vue3】Jest & Vue Test Utils 詳解 チュートリアル
  2. Jestを導入したくてJest入門しました【マッチャー関数編】
  3. jestを完全に理解したい(jest.fn()編) #JavaScript - Qiita
  4. Jestで既存の関数をモック化する方法 #React - Qiita