如何验证setState接收回调函数时状态已更新为指定值?
测试回调式setState的状态更新验证
假设我们有如下父组件代码:
function ParentComponent() { const [state, setState] = useState({ name: 'Rob', age: '55' }); return <ChildComponent state={state} setState={setState} />; }
当子组件直接以对象形式调用setState时:
setState({ name: 'Alice', age: 44 });
我们可以用Jest模拟setter来测试:
const mockSetter = jest.fn(); render(<ChildComponent state={{ name: 'Rob', age: 55 }} setState={mockSetter} />); // 与子组件交互触发setState调用 expect(mockSetter).toHaveBeenCalledWith({ name: 'Alice', age: 55 });
但如果子组件以回调函数形式调用setState(如下示例):
setState(prevState => ({ ...prevState, name: 'Alice' }))
此时mockSetter会收到一个函数,原有的toHaveBeenCalledWith检查不再有效。在测试环境无法直接引用state变量的情况下,该如何验证状态已更新为{ name: 'Alice', age: 55 }?
解决方案
你可以手动提取mockSetter接收到的回调函数,传入初始state后验证返回的新状态:
- 确认
mockSetter被调用时传入的是函数 - 取出这个回调函数并执行,传入初始的state值
- 断言执行后的返回值是否符合预期
具体测试代码如下:
const mockSetter = jest.fn(); const initialState = { name: 'Rob', age: 55 }; render(<ChildComponent state={initialState} setState={mockSetter} />); // 与子组件交互触发setState调用 // 取出传入的回调函数 const updateCallback = mockSetter.mock.calls[0][0]; // 执行回调,传入初始state const newState = updateCallback(initialState); // 验证返回的新状态 expect(newState).toEqual({ name: 'Alice', age: 55 }); // 也可以额外验证mockSetter确实被传入了一个函数 expect(typeof updateCallback).toBe('function');
内容的提问来源于stack exchange,提问作者Vitaly
相关产品推荐
相关产品推荐

