反应测试库-避免getBy?

时间:2019-11-14 12:39:47

标签: javascript reactjs testing jestjs react-testing-library

在使用React Testing Library测试组件时,我发现自己以getBy*开头,偶尔需要用queryBy*替换它(例如,如果我需要检查元素是否不存在) )。我的测试最终以getByqueryBy的混合形式结束,最近我一直在使用queryBy进行所有操作。

这让我开始思考...是否有理由使用getBy

这样的断言按预期会失败,而无需引发错误:

expect(queryByText('Click me')).toBeInTheDocument();
expect(queryByLabel('Name').value).toBe('George')

如果找不到元素,抛出错误有什么好处?是否有理由不对所有(同步)查询使用queryBy

1 个答案:

答案 0 :(得分:1)

正如您所述,getBy *和queryBy *之间的区别在于,如果找不到元素,而没有找到queryBy *,则getBy *会引发错误。对我来说,如果我期望有东西存在,我将始终使用getBy *,并且仅在断言没有东西的情况下使用queryBy *。如果我不希望出现某个元素,那么我想在测试中尽早了解它,这是在进行getBy *调用的地方。

所以我要说抛出错误的好处是,您始终可以确保测试失败将指向根本问题(无法找到您期望存在的元素),而不是该问题的副作用问题(稍后在测试中尝试使用该元素)。

示例测试:

    const { getByTestId, queryByTestId } = render(getComponent());

    const textInput = queryByTestId("textInput");

    fireEvent.change(textInput, { target: { value: "hello" } });
    fireEvent.change(textInput, { target: { value: "hi" } });

使用queryByTestId,测试输出为:

Unable to fire a "change" event - please provide a DOM element.

      23 |     const textInput = queryByTestId("textInput") as any;
      24 |
    > 25 |     fireEvent.change(textInput, { target: { value: "hello" } });
         |               ^
      26 |     fireEvent.change(textInput, { target: { value: "hi" } });
      27 |

因此它确实表明未找到textInput。如果我将其更改为getByTestId,则输出为

Unable to find an element by: [data-testid="textInput"]

    <body>
      <div>
        <div>
          <button
            type="button"
          >
            Show the Text Input!
          </button>
        </div>
      </div>
    </body>

      21 |     const { getByTestId, queryByTestId, rerender } = render(getComponent());
      22 |
    > 23 |     const textInput = getByTestId("textInput") as any;
         |                       ^
      24 |
      25 |     fireEvent.change(textInput, { target: { value: "hello" } });
      26 |     fireEvent.change(textInput, { target: { value: "hi" } });

在我看来,getBy *错误输出有两个优点:

  1. 它直接指向问题所在的行。在第一种情况下,很难发现查询“ textInput”是问题。但这不太直接。
  2. 当我使用getBy *时,它将自动打印DOM的外观。当确定为什么我要寻找的东西不存在时,这可能会有所帮助。一旦queryBy *测试失败,无论如何,这很可能是我要采取的第一步,因此很高兴它会自动存在。

这些边际开发经验的改进值得使用getBy *品种作为我的默认值。通常,我只在测试中使用getBy *,而在断言不存在某些重要内容时仅使用queryBy *。当然也可以只使用queryBy *,如果您发现同时使用两者的成本超过收益,则可以自由使用。