在使用React Testing Library测试组件时,我发现自己以getBy*
开头,偶尔需要用queryBy*
替换它(例如,如果我需要检查元素是否不存在)。我的测试最后以getBy
和queryBy
混合使用,最近我一直在使用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/