React 测试库 - 在 fireEvent 之后使用“await wait()" [英] React Testing Library - using 'await wait()' after fireEvent

查看:42
本文介绍了React 测试库 - 在 fireEvent 之后使用“await wait()"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用测试库在 fireEvent.click 之后检查 DOM 元素.我知道我需要在 fireEvent 之后等待,但不知道为什么简单地使用 await 不起作用?下面是用两种方式编写的相同测试——第一个失败,第二个通过.我不明白为什么第一个失败......非常感谢您的任何见解!

I'm trying to use Testing Library to check for DOM Elements after a fireEvent.click. I know I need to wait after the fireEvent, but am not sure why simply using await doesn't work? Below is the same test written two ways -- the first one fails, the second passes. I don't understand why the first one fails...am very grateful for any insights!

附言-- 我知道 wait 已被弃用,waitFor 是首选,但是由于某些限制,我目前无法更新版本:(

p.s. -- I know wait is deprecated and waitFor is preferred, however due to some constraints I can not update the version at this time :(

未通过测试

// 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');
        
    });

PASSING TEST -- 为什么这个通过,但第一个失败?

PASSING TEST -- Why does this pass but first one fails?

// 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');
      })  
    });

推荐答案

5 个月后我回来回答我的问题(自从发布这个问题后我学到了很多东西哈哈)...

5 months later I'm coming back to answer my question (I've learned a lot since posting this question lol)....

首先,由于是 5 个月后,我想强调的是,如果可能,最好使用 userEvent 库而不是 fireEvent.

First of all, since it is 5 months later I want to underscore that it is better to use the userEvent library instead of fireEvent if possible.

我也不会指出代码中有很多反模式......你应该只在 waitFor 中做出一个断言.您应该避免使用 getByTestId 以支持更易于访问的替代方法.

I also would be remiss to not call out that there are a lot of antipatterns in the code ...You should only ever make one assertion in waitFor. You should avoid using getByTestId in favor of more accessible alternatives.

最后,第一个测试失败的原因是您不能将 waitgetBy* 一起使用.getBy 不是异步的,不会等待.这本来是更好的解决方案:

And finally the reason the first test was failing is that you can not use wait with getBy*. getBy is not async and will not wait. This would have been the better solution:

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

然后测试将等待 nameWrapper 元素可用.

Then the test would have waited on the nameWrapper element to be available.

第二个测试通过,因为 getBy 包含在 RTL 的异步实用程序 wait 中(wait 现在已弃用,取而代之的是 waitFor).这基本上是 findBy 在幕后所做的 - findBygetBy 的异步版本.

The second test passed because getBy is wrapped in RTL's async utility, wait (wait is now deprecated in favor of waitFor). That is essentially what findBy does under the hood -- findBy is the async version of getBy.

当我发布问题时,我并没有完全理解 await 是一个 Javascript 关键字(并且只是语法糖,使代码等待解决的承诺).wait(现在是 waitFor)是 RTL 中的一个实用程序,它将使测试的执行等待直到回调没有抛出错误.

When I posted the question I didn't fully understand that await is a Javascript key word (and just syntactical sugar to make code wait on a promise to resolve). wait (now waitFor) is a utility from RTL that will make execution of the test wait until the callback does not throw an error.

这篇关于React 测试库 - 在 fireEvent 之后使用“await wait()"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆