我正在尝试使用测试库来检查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');
})
});
1条答案
按热度按时间cld4siwp1#
5个月后,我回来回答我的问题(我已经学到了很多,因为张贴这个问题哈哈)。
首先,由于已经过了5个月,我想强调的是,如果可能的话,最好使用
userEvent
库而不是fireEvent
。我也会疏忽,没有呼吁在代码中有很多反模式.你应该永远只在
waitFor
中做一个Assert。您应该避免使用getByTestId
,而使用更易于访问的替代方案。最后,第一个测试失败的原因是您不能将
wait
与getBy*
一起使用。getBy
不是异步的,不会等待。这将是更好的解决方案:然后测试将等待
nameWrapper
元素可用。第二个测试通过了,因为
getBy
被封装在RTL的异步实用程序wait
中(wait
现在被弃用,转而支持waitFor
)。这就是findBy
的本质--findBy
是getBy
的异步版本。当我发布这个问题时,我并不完全理解
await
是一个JavaScript关键词(只是语法上的糖,让代码等待promise来解决)。wait
(现在的waitFor
)是RTL的一个实用程序,它将使测试的执行等待,直到回调不抛出错误。