如何在测试用例中更新Provider包裹的子组件Props?
问题原因
你当前的测试写法存在核心问题:给Provider传入全新的<MyComponent>元素时,旧的MyComponent实例会被卸载,新实例重新挂载。而你绑定spy的是旧实例,自然无法捕获到新实例的方法调用,导致调用次数为0。
解决方案
方案1:直接给子组件实例更新props(非Connected组件适用)
找到MyComponent的wrapper后,直接调用setProps修改它的props,而非替换Provider的children:
it('calls updateTitle when newItems changes', () => { const wrapper = mount( <Provider store={store}> <MyComponent {...props} newItems={0}/> </Provider>, ); const MyComponentWrapper = wrapper.find('MyComponent'); const spy = jest.spyOn(MyComponentWrapper.instance(), 'updateTitle'); // 直接更新子组件的props MyComponentWrapper.setProps({ newItems: 1 }); wrapper.update(); expect(spy).toHaveBeenCalled(); });
方案2:针对Redux Connected组件(通过Store更新)
如果MyComponent是用connect包裹的Redux连接组件,直接给组件setProps不会生效——它的props来自Redux store。此时需要通过修改store状态触发更新:
it('calls updateTitle when newItems changes', () => { const wrapper = mount( <Provider store={store}> <MyComponent {...props} newItems={0}/> </Provider>, ); // 获取Connected组件内部的真实组件实例 const myComponentInstance = wrapper.find('MyComponent').instance().wrappedInstance; const spy = jest.spyOn(myComponentInstance, 'updateTitle'); // 触发store状态更新(示例action需根据你的实际代码调整) store.dispatch({ type: 'UPDATE_NEW_ITEMS', payload: 1 }); wrapper.update(); expect(spy).toHaveBeenCalled(); });
方案3:直接测试未连接的原始组件(推荐)
更简洁的方式是单独测试未被Redux包裹的原始组件(即connect包装前的组件),无需引入Provider,直接控制props:
// 确保你导出了未连接的组件(比如单独export class MyComponent) it('calls updateTitle when newItems changes', () => { const wrapper = mount(<MyComponent {...props} newItems={0}/>); const spy = jest.spyOn(wrapper.instance(), 'updateTitle'); wrapper.setProps({ newItems: 1 }); wrapper.update(); expect(spy).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者Kode_12
相关产品推荐
相关产品推荐

