【发布时间】:2020-11-02 20:13:32
【问题描述】:
我有一个父组件,它执行以下操作:
- 生成包含各种
input字段的表单 - 单击提交按钮时,使用
axios向服务器发出带有<form>数据的POST请求 - 如果返回
Error响应,则会在表单上的<span>元素内呈现错误消息
我正在为此场景编写以下测试
import axios from 'axios';
import { expect } from 'chai';
import { mount } from 'enzyme';
jest.mock('axios');
it('displays an error when the submit fails', async () => {
const wrapper = mount(<MyComponent />);
// Fill in form input fields with text (not shown)
// ....
// ....
// Mock the axios `POST` call to return an error
const errorResponse = { response: { data: { errors: [{ title: 'Some error' }] } } }
axios.post.mockImplementationOnce(() => Promise.reject(errorResponse));
// Click Submit and wait on the axios Promise to complete
const submit = wrapper.find('.my-component__submit-btn').first();
await submit.simulate('click');
// Check if error was rendered on the form
wrapper.update();
const error = wrapper.find('.my-component__submit-error').first();
expect(error).to.have.text('Some error'); // This fails!
});
最后一个 expect() 失败 - 没有设置错误,但我希望存在错误。
但是,如果我通过 setTimeout 添加人为延迟,它就会通过。很明显,这是一个问题,即 React 组件树在 expect() 检查它之前没有更新。
有没有一种干净的方法可以在 React 树上“等待”以重新渲染而不使用 setTimeout?
我以为wrapper.update() 会这样做,但似乎没有。
谢谢!
【问题讨论】:
-
请不要描述您的代码,而是发布它。见stackoverflow.com/help/mcve。等待 Axios 返回的承诺可能会有所帮助,但这取决于。
-
您可以尝试在最后一个
expect之后添加done(); 吗?虽然您已经在使用async-await。可能遗漏了异步调用/承诺。 -
@jegtugado - 不幸的是,
done()在这里不起作用。通过阅读这些文档,似乎调用done()是一种向 Jest 表明您的回调或异步进程已触发的方式。这对承诺很有用,但在我的情况下,我正在等待 render 完成,除非我从组件本身调用done(),否则我看不到这样做的方法(例如,我将其作为prop传递)。 -
发布您的组件 (
<MyComponent />) 代码可能有助于提供更好的答案。 -
只有在检测到更改时才会重新渲染组件。你能验证组件的状态是否发生了变化吗?
标签: javascript reactjs jestjs axios enzyme