Jest.js React测试库-在fireEvent之后使用'await wait()'

pexxcrt2  于 2023-09-28  发布在  Jest
关注(0)|答案(1)|浏览(166)

我正在尝试使用测试库来检查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');
      })  
    });
cld4siwp

cld4siwp1#

5个月后,我回来回答我的问题(我已经学到了很多,因为张贴这个问题哈哈)。
首先,由于已经过了5个月,我想强调的是,如果可能的话,最好使用userEvent库而不是fireEvent
我也会疏忽,没有呼吁在代码中有很多反模式.你应该永远只在waitFor中做一个Assert。您应该避免使用getByTestId,而使用更易于访问的替代方案。
最后,第一个测试失败的原因是您不能将waitgetBy*一起使用。getBy不是异步的,不会等待。这将是更好的解决方案:

fireEvent.click(button);
const nameWrapper =  await findByTestId('name_wrapper');

然后测试将等待nameWrapper元素可用。
第二个测试通过了,因为getBy被封装在RTL的异步实用程序wait中(wait现在被弃用,转而支持waitFor)。这就是findBy的本质--findBygetBy的异步版本。
当我发布这个问题时,我并不完全理解await是一个JavaScript关键词(只是语法上的糖,让代码等待promise来解决)。wait(现在的waitFor)是RTL的一个实用程序,它将使测试的执行等待,直到回调不抛出错误。

相关问题