简体   繁体   中英

How to test react functional component async call

I have a functional component. Inside the component, I have called SpecialistsListService service. The service called the API via Axios. I have to test the async function getSpecialistsList and useEffect functions but I don't do that anyone helps me to solve the problem. When I used class component I simply call the method like await wrapper.instance.getSpecialistsList() then check the state but the functional component approach are different I think.

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} />
  );
}

Splitting your component into custom hooks and component make your life easier to test and more readable by splitting UI and logic.

The custom hooks will look like this

useSpecialistsList.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;

The component look like this

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} />
  );
}

Now you can test your hooks using "@testing-library/react-hooks"

Test will look like this

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);
    });
})

Here waitForNextUpdate call the useEffect (Generally update the component)

To read more about testing custom hooks use this like

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM