javascript - 如何使用 React Redux 和 Jest 测试 mapStateToProps?
问题描述
当我为我想要测试 mapStateToProps 逻辑的连接的 React 组件创建测试时,我遇到了一个我不知道如何解决的问题。
错误信息
Expected: 1
Received: undefined
24 | it('should show previously rolled value', () => {
25 | // test that the state values were correctly passed as props
> 26 | expect(wrapper.props().lastRolledNumber).toBe(1);
当我检查 wrapper.props() 时,它只返回存储对象而没有属性。
为了确保这不是我的代码,我找到了一个可以简化它的示例,但是在我的应用程序中使用该确切版本时我遇到了同样的问题(选项 #2,https://jsramblings.com/2018/01/ 15/3 方式测试-mapStateToProps-and-mapDispatchToProps.html )
我认为这可能与我在这里提到的 React 16+ 版本有关:https ://airbnb.io/enzyme/docs/api/ReactWrapper/props.html
.props() => 对象
返回包装器根节点的 props 对象。它必须是单节点包装器。该方法是访问节点 props 的可靠方法;wrapper.instance().props 也可以,但在 React 16+ 中,无状态功能组件没有实例。请参阅 .instance() => ReactComponent
有谁知道如何在不直接导出私有 mapStateToProps 函数的情况下以一种很好的方式对其进行测试以查看逻辑是否按预期工作?
零件
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
// Component 1 - "Base component"
// Exporting it is a good practice for testing its own logic
export const Dice = ({ lastRolledNumber, onRollDice }) => (
<div>
<p>The last rolled number was {lastRolledNumber}.</p>
<button onClick={onRollDice}>Roll dice</button>
</div>
);
Dice.propTypes = {
lastRolledNumber: PropTypes.number.isRequired,
onRollDice: PropTypes.func.isRequired
}
const mapStateToProps = (state) => ({
lastRolledNumber: state.lastRolledNumber
});
const mapDispatchToProps = (dispatch) => ({
onRollDice: () => dispatch({ type: 'ROLL_DICE' })
});
// Component 2 - Container component
// Export it as a default export
export default connect(mapStateToProps, mapDispatchToProps)(Dice);
测试
import React from 'react';
import { shallow } from 'enzyme';
import '../test-config'; // Setup Enzyme & Adapter
import DiceContainer from './Dice';
// Create the mock store
import configureMockStore from 'redux-mock-store';
const mockStore = configureMockStore();
describe('Dice', () => {
let wrapper, store;
beforeEach(() => {
const initialState = {
lastRolledNumber: 1
};
store = mockStore(initialState);
// Shallow render the container passing in the mock store
wrapper = shallow(
<DiceContainer store={store} />
);
});
it('should show previously rolled value', () => {
// test that the state values were correctly passed as props
expect(wrapper.props().lastRolledNumber).toBe(1);
});
it('should roll the dice again when button is clicked', () => {
// test that the component events dispatch the expected actions
wrapper.simulate('rollDice');
const actions = store.getActions();
expect(actions).toEqual([ { type: 'ROLL_DICE' } ]);
});
});
解决方案
你快到了。您需要调用.dive()方法,以便您可以获取Dice
组件,而不是由模块的HOCDiceContainer
包装的组件。connect
react-redux
简短的回答:
wrapper = shallow(<DiceContainer store={store} />).dive();
一个完整的工作示例:
index.jsx
:
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
export const Dice = ({ lastRolledNumber, onRollDice }) => (
<div>
<p>The last rolled number was {lastRolledNumber}.</p>
<button onClick={onRollDice}>Roll dice</button>
</div>
);
Dice.propTypes = {
lastRolledNumber: PropTypes.number.isRequired,
onRollDice: PropTypes.func.isRequired,
};
const mapStateToProps = (state) => ({
lastRolledNumber: state.lastRolledNumber,
});
const mapDispatchToProps = (dispatch) => ({
onRollDice: () => dispatch({ type: 'ROLL_DICE' }),
});
export default connect(mapStateToProps, mapDispatchToProps)(Dice);
index.test.jsx
:
import React from 'react';
import { shallow } from 'enzyme';
import configureMockStore from 'redux-mock-store';
import DiceContainer from '.';
const mockStore = configureMockStore();
describe('Dice', () => {
let wrapper;
let store;
beforeEach(() => {
const initialState = {
lastRolledNumber: 1,
};
store = mockStore(initialState);
wrapper = shallow(<DiceContainer store={store} />).dive();
});
it('should show previously rolled value', () => {
expect(wrapper.props().lastRolledNumber).toBe(1);
});
it('should roll the dice again when button is clicked', () => {
wrapper.simulate('rollDice');
const actions = store.getActions();
expect(actions).toEqual([{ type: 'ROLL_DICE' }]);
});
});
单元测试结果:
PASS src/stackoverflow/59771991/index.test.jsx (9.645s)
Dice
✓ should show previously rolled value (19ms)
✓ should roll the dice again when button is clicked (2ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 11.505s
测试覆盖率html报告:
推荐阅读
- html - 在 NodejS 中创建包含链接的二维码
- android - 前台服务中的位置,具有后台权限 VS 仅在应用程序中权限 Android Q
- matlab - 在 MATLAB 中有效地找到三个 char 向量的唯一三元组
- excel - 在 Excel VBA 中插入空白行
- javascript - RxJS:模仿 Angulars @Input() 绑定?
- asp.net - 如何将我的应用程序信任级别更改为中等级别?
- azure - 如何处理 Azure 数据湖 Gen2 中的遥测 json 消息?
- android - 如何在 Cordova Android 平台上获取绝对罗盘航向
- r - R pmg 中的 Fama Macbeth 回归
- javascript - 如何从 Cesium3DTileset 控制基元的可见性