iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0

首先我們要測試昨天的Login

  1. 我們要測試login function 沒有問題
  2. 我們要測試沒有放帳號或密碼要跳錯誤
  3. 如果有Error要回傳Error
import { renderHook, act, waitFor } from "@testing-library/react";
import axios from "axios";
import useLogin from "./useLogin";
// import "@testing-library/jest-dom";

// Mock axios.post
jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe("useLogin", () => {
  afterEach(() => {
    // Clear all instances and calls to constructor and all methods:
		// 每次測試結束要清除
    mockedAxios.post.mockClear();
  });

  it("handles login correctly", async () => {
    const { result } = renderHook(() => useLogin());

    act(() => {
      result.current.login("testAccount", "testPassword");
    });

    waitFor(() => {
      expect(axios.post).toHaveBeenCalledWith("api", {
        account: "testAccount",
        password: "testPassword",
      });
    });
  });

  it("sets error if account is not provided", () => {
    const { result } = renderHook(() => useLogin());

    act(() => {
      result.current.login("", "testPassword");
    });

    expect(result.current.error).toBe("請輸入帳號");
  });

  it("sets error if password is not provided", () => {
    const { result } = renderHook(() => useLogin());

    act(() => {
      result.current.login("testAccount", "");
    });

    expect(result.current.error).toBe("請輸入密碼");
  });

  it("handles error on failed axios request", async () => {
    mockedAxios.post.mockRejectedValueOnce(new Error("Some error occurred"));

    const { result } = renderHook(() => useLogin());

    act(() => {
      result.current.login("testAccount", "testPassword");
    });

    waitFor(() => {
      expect(result.current.error).toBe("Error: Some error occurred");
    });
  });
});

接下來我們也順便測試Component本人

getByPlaceholderText 可以找到placeholder相同值的DOM

getByText 可以找到一樣textDOM

fireEvent.change 是用於模擬 React 中的用戶輸入事件,它可以讓我們模擬用戶在輸入字段中輸入值的情況

fireEvent.click就是模擬點擊事件

import React from "react";
import { render, fireEvent, screen } from "@testing-library/react";
import Login from "./page";
import axios from "axios";

// 一樣先把axios改成mock的形式
jest.mock('axios', () => ({
  post: jest.fn(() => Promise.resolve({ data: {} })),
}));

describe("Login Component", () => {
  it("should call login function with the correct arguments when Sign In button is clicked", () => {
    render(<Login />);

    // Find the input fields and button
    const accountInput = screen.getByPlaceholderText("Account");
    const passwordInput = screen.getByPlaceholderText("Password");
    const signInButton = screen.getByText("Sign In");

    // Fill in the input fields
    fireEvent.change(accountInput, { target: { value: "testAccount" } });
    fireEvent.change(passwordInput, { target: { value: "testPassword" } });

    // Click the sign in button
    fireEvent.click(signInButton);

    // Check if login function was called with the correct arguments
    expect(axios.post).toHaveBeenCalledWith("api", {
      account: "testAccount",
      password: "testPassword",
    });
  });
});

其實還有很多可以一起寫進去的,例如你也可以寫測試他輸入值的時候,input有沒有也改成那個數值等等測試,這邊只是一個小實戰練習


上一篇
[Day 26] 實戰時間useLogin
下一篇
[Day 28] useIntersection實戰 做出infinite scroll吧
系列文
React進階班,用typescript與jest製作自己的custom hooks庫30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言