使用React-Router v.5,useHistory,useSelector和useEffect测试React

时间:2020-01-14 14:12:06

标签: reactjs react-hooks enzyme history.js react-testing-library

我很难为保护某些路由并以编程方式重定向未授权用户的组件编写适当的测试。该组件如下所示:

import { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { isAuthed } from 'redux/selectors/auth';

const mapState = state => ({
  isAuthenticated: isAuthed(state),
});

const LoginShield = ({ children }) => {
  const { isAuthenticated } = useSelector(mapState);
  const history = useHistory();

  useEffect(() => {
    if (!isAuthenticated) {
      history.push('/login');
    }
  }, [isAuthenticated]);

  return children;
};

export default LoginShield;

我基本上想检查一下组件是否重定向了未经身份验证的用户,并且没有重定向经过身份验证的用户(两个基本测试用例)。我尝试使用Jest / Enzyme或Jest / ReactTestingLibrary的几种方法,但找不到一个好的解决方案。

目前,我的测试一团糟,但我会分享它,以便有人可以向我展示问题所在:

import React, { useEffect } from 'react';
import { act } from 'react-dom/test-utils';
import { mount } from 'enzyme';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import rootReducer from 'redux/reducers';
import LoginShield from 'components/LoginShield/LoginShield';

describe('LoginShield component', () => {
  let wrapper;
  let historyMock;

  beforeEach(() => {
    const initialState = { auth: { loginId: 'Foo' } };
    const store = createStore(rootReducer, initialState);
    historyMock = {
      push: jest.fn(),
      location: {},
      listen: jest.fn(),
    };
    jest.mock('react-redux', () => ({
      useSelector: jest.fn(fn => fn()),
    }));
    wrapper = mount(
      <Provider store={store}>
        <Router history={historyMock}>
          <LoginShield>
            <h5>Hello Component</h5>
          </LoginShield>
        </Router>
      </Provider>,
    );
  });

  it('renders its children', () => {
    expect(wrapper.find('h5').text()).toEqual('Hello Component');
  });

  it('redirects to the login page if user is not authenticated', async () => {
    await act(async () => {
      await Promise.resolve(wrapper);
      await new Promise(resolve => setImmediate(resolve));
      wrapper.update();
    });
    // is the above necessary?


    console.log(historyMock.push.mock.calls);
    // returns empty array

    // ... ? 

  });

  it('doesn`t redirect authenticated users', () => {
    // .... ?
  });
});

任何提示都值得欢迎!先感谢您。 :)

0 个答案:

没有答案