はじめに
jestを学び始めたばかりで使用方法やセットアップの方法などをまとめることにしました。
セットアップ方法
下記にセットアップの方法についてまとめてみましたので、参考にしていただければと思います。
jestの基本
説明と一緒にサンプルコードを確認していきましょう。
まずテストをするサンプル関数を定義します。こちらの関数を下記例でテストしていきます。
import { jest } from '@jest/globals';//tsconfig.app.jsonに記述する方法もありまである
// サンプル関数
const fetchData = (callback: (data: string) => void) => {
setTimeout(() => {
callback('完了');
}, 100);
};
次にモック関数を用意します。モック関数はテスト専用のダミー関数のことを指します。テスト中の関数の挙動を自由に操作できる利点があります。jest.fn()と記述すること。
// モック関数
const mockCallback = jest.fn();
ここからテストの内容をまとめるdescribe関数を使用します。()内にはまとめたテストの内容がわかるように名前を付けておきます。
describe('非同期 + モック + タイマーのテスト', () => {}
テストの内部でbeforeEach()を使用している場面があります。こちらはテストが行われる前に必ず実行される処理を定義するための関数になります。
beforeEach(() => {
counter = 0; // 変数初期化
jest.useFakeTimers(); // タイマーをモックに切り替え
mockCallback.mockClear(); // モック関数の履歴クリア
});
afterEach関数はテスト後に実行される処理を記述する場所になります。今回はjest.useRealTimers();を記述し、モック化したものを元に戻す処理をしています。
afterEach(() => {
jest.useRealTimers(); // タイマーを元に戻す
});
そしてここからがいよいよテストになります。test関数を使用して実際に確認する内容を中に記述していきます。itと書くこともできますが、処理としては同じになります。
一つ目のテストではcounter正しい値で表示できているかどうかを確認しています。
test('カウンターを増やす', () => {
counter++; // カウンターを1増やす
expect(counter).toBe(1); // toBeマッチャーで値をチェック
});
次はモック化した関数であるmockCallback()が呼び出されております。jestが自動で呼び出し履歴を記録します。次の行で格納したデータを使用してconsoleに内容を表示させています。
.mockはjestがモック関数に付与できる特別なオブジェクトです。
.callsは呼び出しごとの引数配列をまとめた配列になります。
lengthは何回呼ばれたか、[0][0]で引数配列の最初と0番目の引数にアクセスできるように記述されています。
test('モック関数を呼ぶ', () => {
mockCallback('データ');
console.log('mockCallback call count:', mockCallback.mock.calls.length);
console.log('mockCallback first args:', mockCallback.mock.calls[0][0]);
});
最後はfetchData関数の中にモック化した関数を引数に入れ、呼び出しております。
同じようにconsoleで値を呼びだそうとしていますが、一つ目のconsoleでは何も表示されません。
タイマーを進めるadvanceTimersByTime()へ100を指定することでfetchDataの中の setTimeout()をテストすることができるようになります。advanceTimersByTime()はフェイクタイマーを使用しているとき使用可能な関数になります。
test('setTimeout を進めてコールバック実行', () => {
fetchData(mockCallback);
// この時点ではまだ呼ばれていない
console.log('呼ばれる前:', mockCallback.mock.calls.length);
// タイマーを進める
jest.advanceTimersByTime(100);
// ここで callback が呼ばれる
console.log('呼ばれた後:', mockCallback.mock.calls.length);
console.log('callback 引数:', mockCallback.mock.calls[0][0]);
});
完成コード
import { jest } from '@jest/globals';//tsconfig.app.jsonに記述する方法もありまである
// サンプル関数
const fetchData = (callback: (data: string) => void) => {
setTimeout(() => {
callback('完了');
}, 100);
};
// モック関数
const mockCallback = jest.fn();
// ============================
// describe でテストをグループ化
// ============================
describe('非同期 + モック + タイマーのテスト', () => {
let counter: number;
// ============================
// beforeEach: 各テスト前に毎回実行
// ============================
beforeEach(() => {
counter = 0; // 変数初期化
jest.useFakeTimers(); // タイマーをモックに切り替え
mockCallback.mockClear(); // モック関数の履歴クリア
});
// ============================
// afterEach: 各テスト後に毎回実行
// ============================
afterEach(() => {
jest.useRealTimers(); // タイマーを元に戻す
});
//test1
test('カウンターを増やす', () => {
counter++; // カウンターを1増やす
expect(counter).toBe(1); // toBeマッチャーで値をチェック
});
// ============================
// モック関数の呼び出し
// ============================
test('モック関数を呼ぶ', () => {
mockCallback('データ');
console.log('mockCallback call count:', mockCallback.mock.calls.length);
console.log('mockCallback first args:', mockCallback.mock.calls[0][0]);
});
// ============================
// タイマー制御 + 非同期テスト
// ============================
test('setTimeout を進めてコールバック実行', () => {
fetchData(mockCallback);
// この時点ではまだ呼ばれていない
console.log('呼ばれる前:', mockCallback.mock.calls.length);
// タイマーを進める
jest.advanceTimersByTime(100);
// ここで callback が呼ばれる
console.log('呼ばれた後:', mockCallback.mock.calls.length);
console.log('callback 引数:', mockCallback.mock.calls[0][0]);
});
});
おわりに
テスト内容の基礎の部分に触れながら、自身も投稿しながらわからないことは調べました。ですが本番のコードに対し、テストを完璧に施せるまでにはまだ時間がかかりそうです。💦
毎日少しずつでも触れながら慣れていこうと思います。
ISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!