简体   繁体   English

Axios 单元测试与 React 测试库和 typescript

[英]Axios unit test with React testing library and typescript

I am trying to test an axios API call that happens on onload of a page using react testing library.我正在尝试使用反应测试库测试在页面加载时发生的 axios API 调用。 The mock Axios instance seems not firing even after passing the props into the component.即使在将道具传递到组件后,模拟 Axios 实例似乎也没有触发。 I want to test both error and success scenarios.我想测试错误和成功场景。 I have followed many samples but typescript makes my testing harder.我跟踪了许多样本,但 typescript 使我的测试更加困难。 Please help请帮忙

RegistrationConfirm.tsx注册确认.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测试.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);
    }); 

});

Error错误

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

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

Try to render the component inside act() .尝试在act()中渲染组件。 Also call mockImplementation before render function:在渲染 function 之前也调用 mockImplementation:

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

If you have many re-render, you will need to use async-await如果你有很多重新渲染,你将需要使用 async-await

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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