2

就非 API 功能而言,我不擅长编写测试我已经在 rendererHook 的帮助下使用 JEST 进行了测试,就像下面的示例正确 TEST一样:

import { render, screen, cleanup } from '@testing-library/react';
import useAppDrawer from "../../../utils/hooks/useAppDrawer";
import {act,renderHook} from '@testing-library/react-hooks';
import React from "react";

describe("hook: useAppDrawer", () => {

    afterEach(() => {
        cleanup();
    });

    test('drawer open', () => {
        const {result} = renderHook(useAppDrawer);

        act(()=>{
            result.current.handleDrawerOpen();
        })
        expect(result.current.open).toBe(true);

    });
    test('drawer close', () => {
        const {result} = renderHook(useAppDrawer);

        act(()=>{
            result.current.handleDrawerClose();
        })
        expect(result.current.open).toBe(false);

    });

});

但是,如果 JEST 中的 API 调用仍然让我感到困惑,我们该怎么办。我仍然无法理解如何在 JEST 中测试 API 调用,如下面的有问题的函数

import React, {useContext} from "react";
import request from "../services/Http";
import useIsLoading from "./useIsLoading";
import {Context} from "../store/context/store";
import {SET_BOOTHS} from "../store/context/Constants";

export default function useFetchBooths(){

    const {isLoading, setIsLoading} = useIsLoading()
    const [{booths}, dispatch] = useContext(Context)

    function fetchBooths(){

        setIsLoading(true)

        request.get('/event/get-booth-list')
            .then((res) => {
                setIsLoading(false)
                if (res)
                {
                    dispatch({
                        type: SET_BOOTHS,
                        payload: res.data.booth_data
                    })
                }
            })
    }

    function searchBooths(value){

        if (value)
        {
            let obj = booths.filter(booth => booth.booth_name.toLowerCase().includes(value.toLowerCase()));

            if (obj.length > 0)
            {
                dispatch({
                    type: SET_BOOTHS,
                    payload: obj
                })
            }
            else
            {
                fetchBooths()
            }

        }
        else
        {
            fetchBooths()
        }
    }

    return { booths, fetchBooths, isLoading, searchBooths }
}

上述功能可能的开玩笑测试是什么?考虑是否获取展位等情况,因为在这两种情况下,我都将展位价值设为 []。 到目前为止,我的尝试是:

import { render, screen, cleanup, waitFor } from '@testing-library/react';
import useFetchBooths from "../../../utils/hooks/useFetchBooths";
import {act,renderHook} from '@testing-library/react-hooks';
import React from "react";
import * as requestsModule from "../../../utils/services/Http";
import {Store} from "../../../utils/store/context/store";

describe("hook: useFetchBooths", () => {

    afterEach(() => {
        cleanup();
    });

    test('Booth is fetched', async () => {
        const boothData = [
            {
                "message": "Data fetched Successfully",
                "success": true
            }
        ];
        const wrapper = ({children}) => (
            <Store>{children}</Store>
        )
        const {result } = renderHook(() => useFetchBooths(), {wrapper});
         jest.spyOn(result.current, "fetchBooths").mockResolvedValue(boothData);
         console.log(result.current.fetchBooths())
        await expect(result.current.fetchBooths()).resolves.toEqual([{ "success": true, "message": "Data fetched Successfully" }]);

    });

});

上面的测试用例通过了,但这是一个模拟 API(我正在创建数据并将其与我自己的书面数据进行比较,但这不是我想要的)但我想确保我的真实 API 在该测试中正常工作,就像我一样我正在fetchBooths () 函数中获取展位列表,所以当我的一切都依赖于真实 API 时,我如何使用模拟 API 对其进行测试但我在这一点上被严重卡住了。此外,我无法理解searchBooths 函数的测试用例是什么,因为它显示为未定义并且展位列表显示为 [] 尽管它不应该是 [] 我仍然无法找出解决方案。请帮我写这些测试用例

4

1 回答 1

0

在您的测试代码中使用 aspy来模拟 requests 模块:

import * as requestsModule from "../services/Http";

describe("hook: useFetchBooths", () => {

    afterEach(() => {
        cleanup();
    });

    test('Booth is fetched', async () => {

        jest.spyOn(requestsModule, 'get').mockResolvedValue([]) // <-- here you should provide the data you want your hook to see.

        const wrapper = ({children}) => (
            <Store>{children}</Store>
        )

        const {result } = renderHook(() => useFetchBooths(), {wrapper});
        await act(async () => {
            await waitFor(() => result.current.fetchBooths() )
        })

        await act(async () => {
            await waitFor(() => result.current.booths )
            console.log(result.current);
        })
        expect(result.current.booths).toEqual([]);

    });

});

更新:如何模拟 useContext

  1. 创建一个自定义钩子
// boothsContext.js

import {Context} from "../store/context/store";

export const useBoothsContext = () => useContext(Context)

  1. 使用以下方法模拟钩子jest.spyOn
import { wait } from '@testing-library/react'
import * as BoothsContextModule from './boothsContext.js'

...

test('Booth is fetched', async () => {
    const mockDispatch = jest.fn()
    const data = { booths: []} // change this to inject different data into your hook result
    jest.spyOn(BoothsContextModule, 'useBoothsContext')
        .mockReturnValue([data, mockDispatch])

    // perform test steps

   await wait(() => expect(mockDispatch).toHaveBeenCalledWith({
      type: SET_BOOTHS,
      payload: {...} // <-- expected payload you want to assert
   }))

于 2021-08-12T10:59:47.273 回答