如何用Jest和Enzyme测试组件内部方法并Spy this.props.onSave?
我来一步步帮你搞定这两个React组件测试的问题~
1. 如何用Jest和Enzyme测试组件实例内部调用的方法?
核心思路就是监听组件实例上的目标方法,触发调用它的行为,最后验证是否被调用,具体步骤如下:
- 先用Enzyme的
shallow(推荐单元测试用,不渲染子组件)或mount(需要渲染完整组件树时用)渲染组件,拿到组件包裹器。 - 通过
enzymeWrapper.instance()获取组件的实例对象。 - 用Jest的
jest.spyOn()方法,把实例和要监听的方法名传进去,创建一个spy对象。 - 触发会调用该方法的用户行为(比如模拟按钮点击、输入框变化等)。
- 最后用Jest的断言(比如
expect(spy).toHaveBeenCalled())验证方法是否被调用,还可以用toHaveBeenCalledWith()验证传入的参数是否正确。
举个简单例子:如果组件里有个handleSubmit方法,点击提交按钮会触发它,测试代码大概是这样:
describe('MyComponent', () => { it('should call handleSubmit when submit button is clicked', () => { const wrapper = shallow(<MyComponent />); const handleSubmitSpy = jest.spyOn(wrapper.instance(), 'handleSubmit'); wrapper.find('button[type="submit"]').simulate('click'); expect(handleSubmitSpy).toHaveBeenCalled(); }); });
2. 针对AddImage组件测试
this.props.onSave()的Spy方案 你的现有测试已经能监听onContinue了,但onSave是组件接收的props方法,不能直接spy组件实例上的this.props.onSave,正确的做法是在传入props之前就创建好onSave的spy,再把这个spy传给组件,具体修改如下:
完整测试代码示例
describe('AddImage', () => { let enzymeWrapper; let onSaveSpy; let onContinueSpy; beforeAll(() => { // 1. 创建onSave的spy,mock返回resolved的Promise(因为组件里用了.then) onSaveSpy = jest.fn().mockResolvedValue(Promise.resolve()); // 2. 准备props,把spy作为onSave传进去 const props = { onSave: onSaveSpy, // 这里补充组件需要的其他props,比如如果img是来自props的话也要加上 }; // 3. 渲染组件 enzymeWrapper = shallow(<AddImage {...props} />); // 4. 继续监听onContinue(如果需要的话) onContinueSpy = jest.spyOn(enzymeWrapper.instance(), 'onContinue'); }); it('should call onSave when continue button is clicked', async () => { // 模拟按钮点击,触发onContinue enzymeWrapper.find('button').simulate('click'); // 注意:因为onSave返回的是Promise,必须等待异步操作完成再断言 await Promise.resolve(); // 验证onContinue被调用 expect(onContinueSpy).toHaveBeenCalled(); // 验证onSave被调用,如果知道预期的img参数,还可以加上参数验证 expect(onSaveSpy).toHaveBeenCalled(); // 比如如果组件里的img是某个固定值,可以写成: // expect(onSaveSpy).toHaveBeenCalledWith(expectedImgValue); }); });
关键说明
- 为什么要提前创建onSave的spy?因为
this.props.onSave是外部传入的方法,组件只是调用它,所以我们需要让组件拿到的本身就是一个spy,这样才能追踪它的调用情况。 - 必须处理异步:因为
onSave返回Promise,测试用例要加async/await(或者用.then()),否则断言会在Promise resolve之前执行,导致测试失败。 - 如果你的
img变量是组件内部状态或者其他来源,记得在测试里模拟对应的场景,确保onSave能拿到正确的参数。
内容的提问来源于stack exchange,提问作者Aafaq Ahmad
相关产品推荐
相关产品推荐

