javascript - 单击处理程序模拟函数不会被调用
问题描述
我要测试的组件:
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]
但它没有被调用
该应用程序在我手动测试应用程序时工作,所以我想我尝试测试它的方式有问题。
编辑:
我发现了如何使测试通过: In Pad.js
,还导出未包装的组件:
export class UnwrappedPad extends React.Component {
...
}
...
export default connect(mapStateToProps, mapDispatchToProps)(UnwrappedPad);
并且在测试中,使用展开的组件而不是连接的组件。
我仍然不明白为什么它在包装时不起作用connect
。
解决方案
似乎您将处理程序传递给容器,而不是组件。每当您模拟单击时,这就是映射到被调用组件的 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),
]);
});
此外mapStateToProps
,redux 的方法还获得了第二个参数,它是容器自己的 porps。然后我会明确表示该值是通过的。
例如const mapStateToProps = (state, ownProps) => ({ value: ownProps.value});
希望这可以帮助!
推荐阅读
- ios - 我们可以修改现有 IAP(应用内购买)产品的持续时间吗?使用该 IAP 标识符的已订阅用户会发生什么情况?
- excel - Excel VBA 匹配函数返回错误 2042
- gateway - Kong 保护 APIS 和速率限制
- python - 在 sns.histplot 中绘制直方图失败
- ios - 如何修复这个与 Ruby 相关的 Flutter iOS 构建错误?
- python - 在 Linux 上为 Python 3.9 打包 GDAL
- sql - 如何始终只显示 SQL 查询结果表中相同值的第一个值?
- sql - SQL:如何仅将 where 应用于某些字段?
- python - 在 Windows 上将 pytorch 和 matplotlib 与 MKL 一起使用的正确方法是什么?
- javascript - 在for循环中使用时如何为按钮标签提供动态ID