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

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

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

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


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

最佳答案

如您所述,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 *错误输出具有两个优点:


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


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

关于javascript - react 测试库-避免getBy?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58857019/

10-12 04:23