はじめに
Reactでフロントを書き始めて1ページが終わりテストのフェーズに入りました
そしていきなりつまづいたのでAxiosのテストについてまとめます
問題
ReactでAxiosを使ってemail
とpassword
をPOSTして、name
を受け取るリクエストを作成しました
テストをJest(reatc-testing-library)と、testing-library/react-hooksを利用して以下のように書きました
Axiosはモックにして常に同じ結果を返すようにしました
useAuth.tsx
import { renderHook, act } from "@testing-library/react-hooks";
import { useAuth } from "../hooks/useAuth";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
const response = {
data: {
name: "Tarou",
},
};
const mock = new MockAdapter(axios);
mock.onPost(`http://localhost:8080/sign_in`).reply(200, response);
const mockedNavigator = jest.fn();
jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useNavigate: () => mockedNavigator,
}));
describe("useAuthlogin", () => {
it("トップページに遷移すること", () => {
const { result } = renderHook(() => useAuth());
act(() => {
result.current.login("test@example.com", "password");
});
expect(mockedNavigator).toHaveBeenCalledWith("/");
});
});
テストではリクエストがとおると/
にuseNavigate
を利用してページ遷移するので、ページ遷移が行われているかテストしています。しかしこのコードではcase 0
とエラーになり、遷移が行われていないことで失敗してしまいました
解決方法
Axiosは非同期なので、非同期の処理が終わる前にexpect
の評価が行われているためページ遷移が行われていませんでした
login
の処理の実行をasync/await
で待ってからexpect
でテストをすると通りました
useAuth.tsx
import { renderHook, act } from "@testing-library/react-hooks";
import { useAuth } from "../hooks/useAuth";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
const response = {
data: {
name: "Tarou",
},
};
const mock = new MockAdapter(axios);
mock.onPost(`http://localhost:8080/sign_in`).reply(200, response);
const mockedNavigator = jest.fn();
jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useNavigate: () => mockedNavigator,
}));
describe("useAuthlogin", () => {
it("トップページに遷移すること", async () => {
const { result } = renderHook(() => useAuth());
await act(async () => {
await result.current.login("test@example.com", "password");
});
expect(mockedNavigator).toHaveBeenCalledWith("/");
});
});
おわりに
Jestを始めて書いたのがこのテストなのですが、Javascriptのなさを痛感しました
これから先行きが不安です
参考