如何测试反应功能组件异步调用

时间:2021-03-08 11:06:19

标签: javascript reactjs frontend react-testing-library

我有一个功能组件。在组件内部,我调用了 SpecialistsListService 服务。该服务通过 Axios 调用 API。我必须测试 async 函数 getSpecialistsList 和 useEffect 函数,但我不这样做任何人帮助我解决问题。当我使用类组件时,我只是调用像 await wrapper.instance.getSpecialistsList() 这样的方法,然后检查状态,但我认为功能组件的方法是不同的。

import React, { useState, useEffect } from "react";
import SpecialistsListService from "../../../services/specialists";
import SpecialistsPageView from "./SpecialistsPageView";
import "./index.scss";

export default function SpecialistsPage() {
  const [specialistsList, setSpecialistsList] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  const specialistsListService = new SpecialistsListService();

  useEffect(() => {
    getSpecialistsList();
  }, []);

  async function getSpecialistsList() {
    const specialistsListData = await specialistsListService.getSpecialistsList();
    setSpecialistsList(specialistsListData);
    setIsLoading(false);
  }

  return (
    <SpecialistsPageView isLoading={isLoading} specialists={specialistsList} />
  );
}

1 个答案:

答案 0 :(得分:1)

将您的组件拆分为自定义钩子和组件,通过拆分 UI 和逻辑使您的生活更易于测试和更具可读性。

自定义钩子看起来像这样

使用SpecialistsList.js

import { useState, useEffect } from "react";

const useSpecialistsList = (specialistsListService) => {
  const [specialistsList, setSpecialistsList] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    getSpecialistsList();
  }, []);

  async function getSpecialistsList() {
    const specialistsListData = await specialistsListService.getSpecialistsList();
    setSpecialistsList(specialistsListData);
    setIsLoading(false);
  }

  return {
    isLoading: isLoading,
    specialistsList: specialistsList
  }
}

export default useSpecialistsList;

组件看起来像这样

import React from "react";
import SpecialistsListService from "../../../services/specialists";
import SpecialistsPageView from "./SpecialistsPageView";
import useSpecialistsList from "./useSpecialistsList";
import "./index.scss";

export default function SpecialistsPage() {
  const {isLoading, specialistsList} = useSpecialistsList(new SpecialistsListService());

  return (
    <SpecialistsPageView isLoading={isLoading} specialists={specialistsList} />
  );
}

现在你可以使用“@testing-library/react-hooks”来测试你的钩子

测试看起来像这样

import {renderHook} from "@testing-library/react-hooks";
import useSpecialistsList from "./useSpecialistsList";
import SpecialistsListService from "../../../services/specialists";

describe("useSpecialistsList", ()=>{
  
    it('Should return userDetails loading as false', async ()=> {
        const {result, waitForNextUpdate} = renderHook(()=> useSpecialistsList(new SpecialistsListService()));
        
        expect(result.current.isLoading).toEqual(true);

        await waitForNextUpdate();

        expect(result.current.isLoading).toEqual(false);
    });
})

这里waitForNextUpdate调用useEffect(一般更新组件)

要阅读有关测试自定义钩子的更多信息,请使用 this like