我要测试的组件:
import React from 'react';
import { connect } from 'react-redux';
import { actionCreators as calculatorActionCreators } from './calculator';
class Pad extends React.Component {
handleClick = () => {
this.props.add(this.props.value);
};
render() {
return (
<div className="pad" onClick={this.handleClick}>
{this.props.display}
</div>
);
}
}
const mapStateToProps = state => ({});
const mapDispatchToProps = dispatch => ({
add: val => dispatch(calculatorActionCreators.addExpression(val)),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Pad);
测试:
import React from 'react';
import store from './store';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Pad from './Pad';
it('adds calculation steps', () => {
const mockAdd = jest.fn();
const value = 1;
const element = mount(
<Pad
store={store}
value={value}
add={mockAdd}
/>
);
const clickable = element.find('.pad');
clickable.simulate('click');
expect(mockAdd).toHaveBeenCalledWith(value);
});
我希望.pad
元素上的模拟点击会调用handleClick
,因此this.props.add
会被调用。但是当我运行测试时,我收到了这个错误:
已调用的预期模拟函数: [1]
但它没有被称为
当我手动测试应用程序时,该应用程序正常工作,所以我想我尝试测试它的方式有问题。
修改
我发现了如何通过测试:
在Pad.js
中,还要导出未包装的组件:
export class UnwrappedPad extends React.Component {
...
}
...
export default connect(mapStateToProps, mapDispatchToProps)(UnwrappedPad);
在测试中,使用未包装的组件而不是连接的组件。
我仍然不明白为什么在connect
中包装它时它不起作用。
答案 0 :(得分:2)
好像您将处理程序传递给容器,而不是传递给组件。每当您模拟单击时,这是映射到被调用的组件的props的方法。
所以你有两种可能性。
1)Redux可以帮助您从行为中分离演示文稿,这样您就可以提取您的演示组件并单独测试它。您的测试可能类似于:
it('adds calculation steps', () => {
const mockAdd = jest.fn();
const value = 1;
const element = mount(<Pad value={value} add={mockAdd}/>);
const clickable = element.find('.pad');
clickable.simulate('click');
expect(mockAdd).toHaveBeenCalledWith(value);
});
你的组件是这样的:
export class Pad extends React.Component {
handleClick = () => {
this.props.add(this.props.value);
};
render() {
return (
<div className="pad" onClick={this.handleClick}>
{this.props.display}
</div>
);
}
}
2)如果你真的想测试集成组件和容器,那么你可以使用像redux-mock-store这样的东西。这将允许您验证通过调度程序触发的操作。你测试可能看起来像这样:
it('adds calculation steps', () => {
const mockStore = configureStore([])
const store = mockStore({})
const value = 1;
const element = mount(
<Provider store={store}>
<Pad value={value}/>
</Provider>
);
const clickable = element.find('.pad');
clickable.simulate('click');
expect(store.getActions()).toHaveBeenCalledWith([
calculatorActionCreators.addExpression(val),
]);
});
还有来自redux的mapStateToProps
方法得到第二个参数,它们是容器的自己的porps。然后我会明确表示该值是通过的。
e.g。 const mapStateToProps = (state, ownProps) => ({ value: ownProps.value});
希望这有帮助!