【问题标题】:Testing HOC with Recompose使用 Recompose 测试 HOC
【发布时间】:2019-02-27 19:36:30
【问题描述】:

我在测试一个 prop 在我的 HOC 上被触发时遇到了一些麻烦。

import { connect } from 'react-redux';
import { compose, lifecycle } from 'recompose';

import { fetchCurrentUser } from '../../actions/users';
import { getUser } from '../../reducers/users';
import User from '../../models/User';

export default Component => compose(
  connect(state => ({
    user: getUser(state),
  }),
  { fetchCurrentUser }),
  lifecycle({
    componentDidMount() {
      if (this.props.user instanceof User) return;
      this.props.fetchCurrentUser();
    },
  }),
)(Component);

我想知道fetchCurrentUser 是否在user 不是用户实例时触发。

到目前为止,我的测试中有这个:

it.only('fetches user if user is not a User instance', () => {
  const setup = () => {
  const props = {
    user: 'string',
    fetchCurrentUser: jest.fn(),
   };
   const enzymeWrapper = mounting(props);

   return {
     props,
      enzymeWrapper,
    };
  };

  // That returns 0 so false         
  expect(setup().props.fetchCurrentUser.mock.calls.length).toEqual(1);
});

似乎我无法以这种方式替换道具。如果我在生命周期方法中记录this.props,我永远不会看到user: 'string'

提前致谢

【问题讨论】:

    标签: reactjs testing higher-order-components recompose


    【解决方案1】:

    您需要对组件进行浅层安装以测试其功能。

    it.only('fetches user if user is not a User instance', () => {
      const setup = () => {
      const props = {
        user: 'string',
        fetchCurrentUser: jest.fn(),
       };
       // shallow render the component
       const enzymeWrapper = shallow(<Component {...props} />)
    
       return {
          props,
          enzymeWrapper,
        };
      };
    
      expect(setup().props.fetchCurrentUser.mock.calls.length).toEqual(1);
    });
    

    【讨论】:

    • 感谢您的回答。这仍然不能将 HOC 上的 fetchCurrentUser 交换为我在测试中通过的模拟。我尝试在浅层组件上使用 .dive() 几次,然后我看到代码在 componentDidMount 内到达,但函数不是模拟的
    • 看来,当connect 将该道具传递给下一个 HOC 时,它优先于测试中通过的道具...
    • @GotTheFeverMedia,是的,这会发生,为了使测试正常工作,您可能可以拆分组件而不单独连接并对其进行测试
    • 好吧,不知何故,你的想法成功了…… :D 我会发布完整的答案,但投票给你的是正确的。谢谢
    【解决方案2】:

    好的,在shubham-khatri 的帮助下,我做了以下工作。

    将组件分成 2 个不同的组件,并仅通过调用测试一个组件。这样我就可以模拟测试中通过的道具。

    组件:

    import { connect } from 'react-redux';
    import { compose, lifecycle } from 'recompose';
    
    import { fetchCurrentUser } from '../../actions/users';
    import { getUser } from '../../reducers/users';
    import User from '../../models/User';
    
    const Connected = connect(state => ({
      user: getUser(state),
    }),
    { fetchCurrentUser });
    
    export const Enhanced = lifecycle({
      componentDidMount() {
        if (this.props.user instanceof User) return;
    
        this.props.fetchCurrentUser();
      },
    });
    
    export default Component => compose(
      Connected,
      Enhanced,
    )(Component);
    

    测试:

    describe('Fetching user', () => {
        const setup = (moreProps) => {
          const props = {
            fetchCurrentUser: jest.fn(),
            ...moreProps,
          };
    
          const EnhancedStub = compose(
            Enhanced,
          )(Component);
    
          const enzymeWrapper = shallow(
            <EnhancedStub {...props} />,
          );
    
          return {
            props,
            enzymeWrapper,
          };
        };
    
        it('fetches user if user is not a User instance', () => {
          expect(setup().props.fetchCurrentUser.mock.calls.length).toEqual(1);
        });
    
        it('does NOT fetch user if user is a User instance', () => {
          expect(setup({ user: new User({ first_name: 'Walter' }) }).props.fetchCurrentUser.mock.calls.length).toEqual(0);
        });
      });
    

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-09-06
      • 2018-02-02
      • 2017-11-23
      • 2021-05-09
      • 2018-03-16
      • 2019-08-26
      • 1970-01-01
      • 2021-04-18
      • 2018-11-04
      相关资源
      最近更新 更多