【问题标题】:Axios unit test with React testing library and typescript使用 React 测试库和 typescript 进行 Axios 单元测试
【发布时间】:2020-12-03 11:51:24
【问题描述】:

我正在尝试使用反应测试库测试在页面加载时发生的 axios API 调用。即使在将道具传递给组件之后,模拟 Axios 实例似乎也没有触发。我想测试错误和成功场景。我跟踪了许多样本,但打字稿使我的测试更加困难。请帮忙

RegistrationConfirm.tsx

export default function RegistrationConfirm(props: any) {
    const [statusMessage, setStatusMessage]  = useState('Confirming your account ...');
    const confirmPostAPI = async (param1: string, param2: string) => {    
        try {
            const res =  await Axios({
                method: 'post',
                url: `${BASE_API_URL}User/registration/confirm?${param1}&${param2}`
            });
            setStatusMessage('Thank you for registering ');
        } catch (err) {
            if(err.response && err.response.data) {
                setStatusMessage(err.response.data.message);    
            } else {
                setStatusMessage('There is a problem with your confirmation email');    
            }
                    
       }
    }
    useEffect(() => {
        if(props.match && props.match.params) {
            const params = props.match.params;
            const strArray = params.userName.split("&");
            console.log("confirmPostAPI", confirmPostAPI)
            confirmPostAPI( strArray[0],  strArray[1]);
        } else {
            setStatusMessage('There is a problem with your confirmation');
        }
    }, [props])
    
    return (
        <div>
            {statusMessage && <Alert data-testid="confirmStatus">{statusMessage}</Alert>}
        </div>
    )
}

Test.ts

import React from 'react';
import axios from 'axios';
import { cleanup, getByTestId, render, screen, waitFor } from '@testing-library/react';
import RegistrationConfirm from '../presentational/registration-confirm/RegistrationConfirm';
import { createMemoryHistory, createLocation } from 'history';
import { match } from 'react-router';
afterEach(cleanup);
const history = createMemoryHistory();
const path = `/route/:userName=user&confirmationCode=23467236742`;
const mockMatch = {
    isExact: false,
    path,
    url: path.replace(':userName', '1'),
    params: { userName: "email=email&confirmationCode=199579" }
};

const location = createLocation(mockMatch.url);

describe("<RegisterConfirm />",()=> {
    let mockPost: jest.SpyInstance;
jest.mock('axios');
beforeEach(() => {
    mockPost = jest.spyOn(axios, 'post')
});

afterEach(() => {
    jest.clearAllMocks();
});
 
    test("should call confirmpostAPI when the props have values", async() => {    
        const req: any = {
            params: {
                id: 5006
            },
            body: {
               
            }
        };
        const res: any = {
            status: () => {
                return {
                    json: jest.fn()
                }
            },
        };
        const result = {
            status: 200,
            data: {
                "message": "Product saved"
            }
        };

                 render (<RegistrationConfirm history={history}
                location={location}
                match={mockMatchNew}/>);
                mockPost.mockImplementation(() => Promise.resolve(result));                
                console.log('mockPost',mockPost);
            await waitFor(() => screen.getByTestId("confirmStatus"));
            expect(mockPost).toHaveBeenCalledTimes(1);
    }); 

});

错误

expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

【问题讨论】:

    标签: reactjs create-react-app react-testing-library react-typescript jest-mock-axios


    【解决方案1】:

    尝试在act() 中渲染组件。在渲染函数之前也调用 mockImplementation:

    mockPost.mockImplementation(() => Promise.resolve(result)); 
    act(()=> {
      render (<RegistrationConfirm history={history}
    })
    

    如果你有很多重新渲染,你将需要使用 async-await

    mockPost.mockImplementation(() => Promise.resolve(result)); 
    await act(async ()=> {
       render (<RegistrationConfirm history={history}
    })
    

    【讨论】:

    • 我尝试了你的建议。不幸的是得到了同样的错误。
    • 你需要调用 mockPost.mockImplementation(() => Promise.resolve(result));在渲染之前。尝试一下。我在此基础上编辑我的答案。
    猜你喜欢
    • 2015-09-16
    • 2015-09-01
    • 2018-07-26
    • 2021-06-04
    • 2021-07-27
    • 2021-06-07
    • 2017-02-25
    • 2019-04-17
    • 2017-06-21
    相关资源
    最近更新 更多