如何在useEffect react hook中编写用于URL推送的测试用例?

时间:2020-05-21 06:06:16

标签: reactjs react-redux react-router react-hooks enzyme

     afterEach(() => {
        jest.clearAllMocks(); 
      });

      afterAll(() => {
        jest.resetAllMocks(); // clear all the mocks.
      });

      it('Should check the route', () => {
        const wrapper = mount(<Logout />);
        expect(wrapper.find('LoadingMessage')).toBeTruthy();
        expect(useDispatch).toBeCalledTimes(1);
        const mDispatch = useDispatch();
expect(mDispatch).toBeCalledWith({ type: 'USER_LOGOUT' });
    expect(Router.push).toBeCalledWith('/');expect(mDispatch).toBeCalledWith({ type: 'USER_LOGOUT' });
    expect(mDispatch).toBeCalledWith('/');
     })
    })

测试文件

server {
        listen 80;
        listen [::]:80;

        server_name <IP_OR_URL>;

        location / {
             proxy_pass http://localhost:8080/;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header X-Forwarded-Proto $scheme;
             proxy_set_header X-Forwarded-Port $server_port;
        }
}

这是我编写的代码示例,我想为此编写一个测试用例。这样我就可以测试路由器是否正在推送?

想要一些想法或帮助。

谢谢。

1 个答案:

答案 0 :(得分:1)

下面的单元测试解决方案在不使用模拟redux存储的情况下模拟了useDispatch钩子和next/router模块。使用模拟的redux存储并在分派操作后检查存储的状态更接近集成测试。

例如

index.jsx

import React, { useEffect } from 'react';
import Router from 'next/router';
import { useDispatch } from 'react-redux';
import { logout } from './user.actions';
import { LoadingMessage } from './LoadingMessage';

export const Logout = () => {
  const dispatch = useDispatch();
  const props = {
    active: true,
    withOverlay: false,
    small: false,
  };
  useEffect(() => {
    dispatch(logout());
    Router.push('/');
  }, []);
  return (
    <div>
      <LoadingMessage {...props}>
        <div>Logging out, please wait...</div>
      </LoadingMessage>
    </div>
  );
};

user.actions.ts

export function logout() {
  return {
    type: 'LOGOUT',
  };
}

LoadingMessage.jsx

export const LoadingMessage = ({ children }) => <div>{children}</div>;

index.test.jsx

import { Logout } from './';
import { useDispatch } from 'react-redux';
import { mount } from 'enzyme';
import Router from 'next/router';

jest.mock('next/router', () => ({ push: jest.fn() }), { virtual: true });

jest.mock('react-redux', () => {
  const originalReactRedux = jest.requireActual('react-redux');
  const mDispatch = jest.fn();
  const mUseDispatch = jest.fn(() => mDispatch);
  return {
    ...originalReactRedux,
    useDispatch: mUseDispatch,
  };
});

describe('61928263', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should pass without using mock store', () => {
    const wrapper = mount(<Logout></Logout>);
    expect(wrapper.find('LoadingMessage')).toBeTruthy();
    expect(useDispatch).toBeCalledTimes(1);
    const mDispatch = useDispatch(); // get the mocked dispatch function
    expect(mDispatch).toBeCalledWith({ type: 'LOGOUT' });
    expect(Router.push).toBeCalledWith('/');
  });
});

测试结果:

 PASS  stackoverflow/61928263/index.test.jsx (8.62s)
  61928263
    ✓ should pass without using mock store (37ms)

--------------------|---------|----------|---------|---------|-------------------
File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------------|---------|----------|---------|---------|-------------------
All files           |     100 |      100 |     100 |     100 |                   
 LoadingMessage.jsx |     100 |      100 |     100 |     100 |                   
 index.jsx          |     100 |      100 |     100 |     100 |                   
 user.actions.ts    |     100 |      100 |     100 |     100 |                   
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.601s