问题描述
当我尝试直接测试功能selectXHandler
时,我无法声明该功能。由于它是在私有范围内定义的。我无法模拟或监视此功能,因为您无法访问
export const CheckboxWrapper = ({
x,y,z,a = [],}: CheckboxWrapperProps) => {
const State = useContext(Context);
const [state,dispatch] = State;
const { Items } = state;
const selectXHandler = () => {
const payload = {
x,a,};
dispatch({ type: action,payload });
};
if (y) {
return (
<div className="mt5">
<Checkbox
checked={selectedItems[x] !== undefined}
label={z}
onChange={selectXHandler}
/>
</div>
);
}
return null;
};
const selectXHandler = jest.fn();
await fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(selectXHandler).toHaveBeenCalledTimes(1);
我遇到以下错误:
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
解决方法
正如上面评论中所讨论的,测试某些内部组件是不好的举动。想象一下有可能,我们重命名了该内部函数或对其进行内联或拆分为两个。我们的测试会失败吗?绝对是我们的应用程序会坏吗?当然不是。
我们应该绑定到公共接口。对于组件的公共接口是:
-
import
s(例如输入值) - 道具(也是输入值)
- 渲染结果(输出值)
- 使用上下文(也可以当作输入值)
所以我以另一种方式看到测试:
- 一些输入道具
- 我们模拟点击复选框
- 并验证是否已使用某些所需的参数调用了上下文中的
dispatch
。
我对RTL的了解不多,因此我的样本将涉及酶。但是我敢肯定,将其转换为适当的RTL选择器查询会很容易。
import Context from '../where/its/placed/someContext.js';
it('dispatch is called with A on checkbox is clicked',() => {
const dispatch = jest.fn();
const state = {}; // or some initial state your test requires
const ourComponent = mount(<Content.Provider value={{ dispatch,state }}>
<CheckboxWrapper {...somePropsYouNeed} /></Content.Provider>);
ourComponent.find({label: 'some-label'}).simulate('change');
expect(dispatch).toHaveBeenCalledWith({ type: 'someType',payload: 'somePayload' });
expect(dispatch).toHaveBeenCalledTimes(1);
});