はじめに
こんにちは!POMです。
React × TypeScriptでの学習記録アプリ開発において、
Vitest/React Testing Libraryによる
テストを実装していましたが、
その際に出た表記のエラー解決方法について記事に残します。
今回開発したアプリの詳細については、
下記記事になります。
問題
学習記録を新規登録できているかのテストにおいて、
Supabase上の実データに依存しないように、
Supabaseと通信する部分についてはモックにしたテスト実装を
行っていた際に、下記エラーが出ました。
expected 2 to be 3 // Object.is equality
解決方法
【修正前】
const mockInitRecords = [
new Record("1", "test1", 10),
new Record("2", "test2", 20),
];
const mockRecords = vi.fn().mockResolvedValue(mockInitRecords);
vi.mock("@/lib/record", () => {
return {
GetAllRecords: () => mockRecords(),
InsertRecord: vi.fn(),
UpdateRecord: vi.fn(),
};
});
describe("シン・学習記録アプリ", () => {
beforeEach(() => {
render(<StudyRecord />);
});
test("登録できること", async () => {
const before = await screen.findAllByTestId("record");
const openAddModalButton = await screen.findByRole("button", { name: "新規登録" });
fireEvent.click(openAddModalButton);
const inputTitle = await screen.findByLabelText("学習内容");
const inputTime = await screen.findByLabelText("学習時間");
const submitButton = await screen.findByRole("button", { name: "登録" });
// テスト用の記録を入力して登録
fireEvent.change(inputTitle, { target: { value: "テスト記録" }, });
fireEvent.change(inputTime, { target: { value: "2" }, });
fireEvent.click(submitButton);
await waitFor(async () => {
const after = await screen.findAllByTestId("record");
expect(after.length).toBe(before.length + 1);
});
});
});
export class Record {
constructor(
public id: string | undefined,
public title: string,
public time: number
) {}
public static newRecord(
id: string | undefined,
title: string,
time: number
): Record {
return new Record(
id,
title,
time
);
}
}
原因はモック部分で
InsertRecord: vi.fn(),
としており、何もしないことになっていたからでした。
- GetAllRecords() → 2件表示
- 登録ボタン押す
- InsertRecord()が呼ばれる
- データは増えない → テーブルは2件のまま
そこでexpected 3 received 2となり、表記のエラーになっていました。
【修正後】
InsertRecordでrecordsを増やすモックに修正。
const mockInitRecords = [
new Record("1", "test1", 10),
new Record("2", "test2", 20),
];
const mockRecords = vi.fn().mockResolvedValue(mockInitRecords);
vi.mock("@/lib/record", () => {
return {
GetAllRecords: () => mockRecords(),
InsertRecord: vi.fn(async (record: Record) => {
mockInitRecords.push(record);
}),
(略)
};
});
合わせてbeforeEach部分でテストごとにモックデータを
初期状態に戻すようにも修正しています。
describe("シン・学習記録アプリ", () => {
beforeEach(() => {
mockInitRecords.length = 0;
mockInitRecords.push(
new Record("1", "test1", 10),
new Record("2", "test2", 20)
);
render(<StudyRecord />);
});
(略)
});
おわりに
いざ修正前のコードを見ると
そりゃあそうだよな・・・というところで
エラーになっているのですが、
沼にハマっていると実際のテスト部分のコードしか
見ていなかったりと意外と気づかないものです。
切り分けしながら、
処理の流れを丁寧に追っていきたいです。
参考
今回直したソースコードの詳細はGitHubにて。
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼