React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps

Posted

技术标签:

【中文标题】React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps【英文标题】:React Redux: Testing mapStateToProps and mapDispatchToProps with Enzyme/Jest 【发布时间】:2019-01-27 07:42:53 【问题描述】:

所以我想用 Enzyme/Jest 测试 mapStateToPropsmapDispatchToProps

我有一个像这样的组件 DrawerAvatar:

DrawerAvatar.js

const mapStateToProps = state => (
  isAuthenticated: state.authReducer.isAuthenticated
);

export default compose(
  connect(mapStateToProps, null)
)(DrawerAvatar);

DrawerAvatar.test.js

import configureMockStore from 'redux-mock-store';
import connectedDrawerAvatar,  DrawerAvatar  from './DrawerAvatar';

const mockStore = configureMockStore();

it('mapStateToProps should return the right value', () => 
  const initialState = 
    someState: 123
  ;
  const store = mockStore(initialState);
  const wrapper = shallow(<connectedDrawerAvatar store=store />);
  expect(wrapper.props().someState).toBe(123);
);

但是,这不起作用,因为 wrapper.props().someState 返回 undefined... 所以我不知道如何使用连接的组件测试 mapStatesToProps 和 redux-mock-store。

我也不知道如何测试 mapDispatchToProps ..! 我已经尝试过blog 中提供的方法,但它不起作用。

非常感谢!

编辑: 这可行,但我不确定它是否真的测试 mapStateToProps...有人可以确认这是测试 mapStateToProps 的正确方法吗? DrawerAvatar.test.js

  it('mapStateToProps should return the right value', () => 
    const initialState = 
      isAuthenticated: false
    ;
    const mockStore = configureMockStore();
    const store = mockStore(initialState);

    const wrapper = shallow(<connectedDrawerAvatar store=store />);
    expect(wrapper.props().store.getState().isAuthenticated).toBe(false);
  );

【问题讨论】:

看看使用 mount 而不是 shallow 并查看允许您传递上下文的第二个参数 我已经检查过了,但我真的不明白上下文到底是什么......你能提供一些代码 sn-p 来说明你的想法吗? mapDispatchToProps测试可以查看***.com/a/55814950/1897654 【参考方案1】:

我从 redux discussion on github 找到的一种方法是

import React from 'react';
import  shallow  from 'enzyme';
import configureMockStore from 'redux-mock-store';

import ConnectedDrawerAvatar from './DrawerAvatar';
describe('DrawerAvatar', ()=> 
    const mockStore = configureMockStore();

    it.each([true, false], 'receives correct value from store as props', (value)=> 
        const initialState =  authReducer:  isAuthenticated: value  
        const store = mockStore(initialState)

        const wrapper = shallow(<ConnectedDrawerAvatar store=store />)
        expect(wrapper.props().isAuthenticated).toBe(value)
    )
)

【讨论】:

【参考方案2】:

你也可以试试这个:

在我看来,测试 mapStateToProps(),您需要识别特定状态的道具。还使用了提供程序,它使包装在 Connect() 函数中的组件可用。

import React from 'react';
import  shallow  from 'enzyme';
import  Provider  from 'react-redux';
import configureMockStore from 'redux-mock-store';
import ConnectedDrawerAvatar from './DrawerAvatar';

describe('DrawerAvatar', ()=> 
  let component;
  let store;
  let value;

 beforeEach(() => 
    const initialState = 
        authReducer:  isAuthenticated: value 
    ;
    store = mockStore(initialState);
    component = shallow(<Provider store=store><ConnectedDrawerAvatar/></Provider>);
  );

 it('should return exact value from the store(props)', () => 
     expect(component.props().isAuthenticated).toBe(value);
  );


);

希望这会有所帮助!

【讨论】:

【参考方案3】:

最简单的测试方法是直接对 mapStateToProps 进行测试,如下所示:

export const mapStateToProps = state => (
  isAuthenticated: state.authReducer.isAuthenticated
);

并进行这样的测试:

it('mapStateToProps should return the right value', () => 
  const mockedState = 
    authReducer: 
      isAuthenticated: false
    
  ;
  const state = mapStateToProps(mockedState);
  expect(state).toBeFalsy();
);

但我真的不明白你为什么要这样做。

IMO 你不应该测试连接的组件。只需导出容器类并直接测试。

不应该测试组件连接的原因是它在库本身中测试得很好,所以通过测试你并没有真正增加任何价值。

【讨论】:

感谢您的回答!但是导出像 mapStateToProps 这样的私有方法可能不是一个好主意......而且我已经在使用 redux-mock-store,但这个包仅用于测试与动作相关的东西 AFAIK...... @filipyoo 对不起,我注意到您已经使用它并稍微编辑了我的答案。为什么导出不是一个好主意,你能更明确一点吗?如果那是您真正想要测试的代码,我认为导出它没有任何问题。 是的,我知道 connect 已经从包中进行了全面测试,但 mapStateToProps 和 mapDispatchToProps 没有。而you’re exposing private code of the app as public just for testing, which is a bit of a code smell根据这个blog post 没错。但这真的比渲染需要更多时间的整个事情更糟糕吗?单元测试也应该很快。但是,如果您真的想测试它们,应该这样做,对吗?期望(wrapper.props().isAuthenticated).toBeFalsy(); 这是一个如何验证 props 的示例:airbnb.io/enzyme/docs/api/ReactWrapper/props.html

以上是关于React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps的主要内容,如果未能解决你的问题,请参考以下文章

react系列在React中使用Redux

使用通过 react、redux 和 react-redux 完成的组件以及在 react 应用程序中使用 webpack 构建时出错

react 中的 redux 和react-redux的区别分析

react-redux——使用redux——使用react-redux这个扩展

redux与react-redux

Redux 使用 react-router-redux 连接“块”导航