reactjs - 使用 Jest 和 Enzyme 模拟“提交”后测试更新的状态
问题描述
所以我在 React 中有一个 Classical 组件,RecipesNew,它具有以下初始状态:
this.state = {
recipe: {
title: '',
description: '',
prepTime: '',
cookingTime: ''
},
errors: false
}
它有一个表单和以下 onSubmit 方法:
handleOnSubmit = (e) => {
e.preventDefault()
this.props.startAddRecipe(recipe)
.then(recipe => this.props.history.push(`/recipes/${recipe._id}`))
.catch(err => this.setState({ errors: err }))
}
props 上的 startAddRecipe 方法重新返回一个 Promise,当其中的 axios 调用时,该 Promise 将解析到我的数据库,解析然后分发一个更新 redux 状态的操作。当其中的 axios 调用拒绝时,promise 会拒绝。
我想测试 startAddRecipe 何时拒绝 startAddRecipe 并设置 this.state.errors。
在我的测试文件中,我有一个函数,它返回一个承诺并立即拒绝作为 startAddRecipe 道具传递给 RecipesNew:
const startAddRecipeRejectsSpy = jest.fn((recipeData = {}) => {
return Promise.reject(['Test Error', 'Test Error 2'])
})
这是我在 Promise 拒绝时测试的测试。我假设 state.errors 将用这个数组填充:['Test Error', 'Test Error 2']
test('startAddRecipe rejects correctly', () => {
const wrapper = shallow(<RecipesNew startAddRecipe={startAddRecipeRejectsSpy} />);
const mockRecipe = {
title: 'Test Title',
description: 'Test Description',
prepTime: 10,
cookingTime: 10
}
wrapper.setState({ recipe: mockRecipe })
wrapper.find('form').simulate('submit',{ preventDefault: () => { } })
expect(startAddRecipeRejectsSpy).toHaveBeenLastCalledWith(mockRecipe)
expect(startAddRecipeRejectsSpy(mockRecipe)).rejects.toEqual(['Test Error', 'Test Error 2'])
expect(wrapper.update().state().errors).toBe(['Test Error', 'Test Error 2']);
expect(wrapper.update()).toMatchSnapshot();
})
除了最后2个之外,一切都有效。
倒数第二个说:
Expected: ["Test Error", "Test Error 2"]
Received: false
所以基本上状态似乎没有改变?
最后,最后一个快照不是我所期望的,因为当this.state.errors
不是错误的时候,我映射错误数组并生成一个列表——这个列表不会出现在快照中。
有任何想法吗?我已经阅读了很多关于此的主题,但似乎没有什么与我的问题相匹配。
任何帮助表示赞赏。
谢谢!
解决方案
startAddRecipe 是异步的,因此在测试完成之前它可能不会完成。在检查状态之前,您需要等待 startAddRecipe 完成。您可以通过执行类似的操作确保在检查状态之前刷新所有承诺。
const tick = async () => {
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
};
.
.
test('startAddRecipe rejects correctly', async () => {
const wrapper = shallow(<RecipesNew startAddRecipe={startAddRecipeRejectsSpy} />);
const mockRecipe = {
title: 'Test Title',
description: 'Test Description',
prepTime: 10,
cookingTime: 10
}
wrapper.setState({ recipe: mockRecipe })
wrapper.find('form').simulate('submit',{ preventDefault: () => { } })
await tick();
expect(startAddRecipeRejectsSpy).toHaveBeenLastCalledWith(mockRecipe)
expect(startAddRecipeRejectsSpy(mockRecipe)).rejects.toEqual(['Test Error', 'Test Error 2'])
expect(wrapper.update().state().errors).toBe(['Test Error', 'Test Error 2']);
expect(wrapper.update()).toMatchSnapshot();
})
试一试,让我知道它是否适合你。
推荐阅读
- docker - 在自定义桥接网络中访问具有名称的容器
- firebase - Firebase 关系实体
- math - 乘以 256 有什么作用
- fossil - 使用 Fossil SCM 提供静态文件
- c# - 如何将 HTML 打印为 pdf 文档
- reactjs - 请求的资源上不存在“Access-Control-Allow-Origin”标头 - 尝试使用 Axios 从 REST api 获取数据时
- log4j - Zeppelin log4j 设置不在控制台中打印日志
- javascript - 如何导出要在中间件中使用的 Node MongoDB 驱动程序连接?
- flutter - 字符串 num1=stdin.readLineSync(); 不允许我输入数字,答案显示“空”
- bioinformatics - 蛋白质中原子的杂交(Biopython)