我想为我的反应 component.The 逻辑编写单元测试我想测试的内容在 UseEffect.Please 中找到下面的代码

I want to write unit test for my react component.The logic what i want to test is inside UseEffect.Please find the code below

我在 useEffect 中发出 axios POST 请求,收到值后,我使用 setState 更新我的 link。因此,我想为这个业务逻辑写一个单元测试。这是我的组件代码。

export function Login() {
  const browserUrl = window.location.href;
  const [LoginUrl, setLoginUrl] = useState<string>('');
  useEffect(() => {
    const response = axios.post<LoginUrl>('https://somedomain/getLoginUrl', {
      data: browserUrl,
    });
    response.then((res: LoginUrl) => {
      setLoginUrl(res.LoginUrl);
    });
  }, []);

  return (
    <>
      <LoginLink data-testid="getUrl" href={LoginUrl} style={{ cursor: 'pointer' }}>
        LogIN
      </LoginLink>
    </>
  );
}

这是我的单元测试代码。我正在使用 react-testing-library 和 jest。

it('should display loginurl', async () => {
  const { getByTestId } = render(<Login />);
  axiosMock.post('https://somedomain/getLoginUrl', { data: 'abcgd' }).then(() => {
    res: 'asxed';
  });
  const url = await waitFor(() => getByTestId('show-data'));
  expect(url.getAttribute('href')).toEqual('asxed');
});

我的测试从不更新 LoginUrl 并且始终具有初始值。我的假设是我没有编写 async 测试或反应挂钩测试的正确方法。

可能是你没有正确模拟axios模块。

无论如何,这里有一个你可以参考的工作示例:

Login.tsx:

import React from 'react';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { LoginLink } from './LoginLink';

type LoginUrl = any;

export function Login() {
  const browserUrl = window.location.href;
  const [LoginUrl, setLoginUrl] = useState<string>('');
  useEffect(() => {
    const response = axios.post<LoginUrl>('https://somedomain/getLoginUrl', {
      data: browserUrl,
    });
    response.then((res: LoginUrl) => {
      setLoginUrl(res.LoginUrl);
    });
  }, []);

  return (
    <>
      <LoginLink data-testid="getUrl" href={LoginUrl} style={{ cursor: 'pointer' }}>
        LogIN
      </LoginLink>
    </>
  );
}

LoginLink.tsx:

import React from 'react';

export const LoginLink = (props) => {
  return <a {...props}></a>;
};

Login.test.tsx:

import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { Login } from './Login';
import axios from 'axios';

describe('65336283', () => {
  it('should display loginurl', async () => {
    const postSpy = jest.spyOn(axios, 'post').mockResolvedValueOnce({ LoginUrl: 'asxed' });
    const { getByTestId } = render(<Login />);
    expect(getByTestId('getUrl').getAttribute('href')).toEqual('');
    const url = await waitFor(() => getByTestId('getUrl'));
    expect(postSpy).toBeCalledWith('https://somedomain/getLoginUrl', { data: 'http://localhost/' });
    expect(url.getAttribute('href')).toEqual('asxed');
    postSpy.mockRestore();
  });
});

测试结果:

 PASS  examples/65336283/LoginLink.test.tsx
  65336283
    ✓ should display loginurl (23 ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |      100 |     100 |     100 |                   
 Login.tsx     |     100 |      100 |     100 |     100 |                   
 LoginLink.tsx |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.967 s