我试图在fireEvent.click之后使用测试库检查DOM元素。我知道我需要在fireEvent之后等待,但是不知道为什么简单地使用await不起作用?下面是用两种方法编写的相同测试-第一种失败,第二种通过。我不明白为什么第一个失败了……非常感谢您提供任何见解!
p.s。 -我知道不建议使用wait并且首选waitFor,但是由于某些限制,我目前无法更新版本:(
失败测试
// This test fails with the following error and warning:
// Error: Unable to find an element by: [data-test="name_wrapper"]
// Warning: An update to OnlinePaymentModule inside a test was not wrapped in act(...).
it('this is a failing test...why', async () => {
const { getByText, getByTestId } = render(<Modal {...props} />);
const button = getByText('open modal');
fireEvent.click(button);
const nameWrapper = await getByTestId('name_wrapper');
expect(
nameWrapper.getElementsByTagName('output')[0].textContent
).toBe('Jon Doe');
const numberWrapper = await getByTestId('number_wrapper');
expect(
numberWrapper.getElementsByTagName('output')[0].textContent
).toBe('123456');
});
// This test passes with no warnings
it('this is a passing test...why', async () => {
const { getByText, getByTestId } = render(<Modal {...props} />);
const button = getByText('open modal');
fireEvent.click(button);
await wait(() => {
const nameWrapper = getByTestId('name_wrapper');
expect(
nameWrapper.getElementsByTagName('output')[0].textContent
).toBe('Jon Doe');
const numberWrapper = getByTestId('number_wrapper');
expect(
numberWrapper.getElementsByTagName('output')[0].textContent
).toBe('123456');
})
});
答案 0 :(得分:15)
5 个月后我回来回答我的问题(自从发布这个问题以来我学到了很多东西,哈哈)......
首先,由于是 5 个月后,我想强调的是,如果可能,最好使用 userEvent
库而不是 fireEvent
。
我也不会指出代码中有很多反模式......你应该只在 waitFor
中做出一个断言。您应该避免使用 getByTestId
,而应使用更易于访问的替代方法。
最后,第一个测试失败的原因是您不能将 wait
与 getBy*
一起使用。 getBy
不是异步的,不会等待。这本来是更好的解决方案:
fireEvent.click(button);
const nameWrapper = await findByTestId('name_wrapper');
然后测试会等待 nameWrapper
元素可用。
第二个测试通过了,因为 getBy
包含在 RTL 的异步实用程序 wait
中(wait
现在已被弃用,取而代之的是 waitFor
)。这本质上是 findBy
在幕后所做的 - findBy
是 getBy
的异步版本。
当我发布问题时,我并没有完全理解 await
是一个 Javascript 关键字(并且只是让代码等待解决承诺的语法糖)。 wait
(现在是 waitFor
)是来自 RTL 的实用程序,它将使测试的执行等待直到回调没有抛出错误。