在使用React Testing Library测试组件时,我发现自己以getBy*
开头,偶尔需要用queryBy*
替换它(例如,如果我需要检查元素是否不存在) )。我的测试最终以getBy
和queryBy
的混合形式结束,最近我一直在使用queryBy
进行所有操作。
这让我开始思考...是否有理由使用getBy
?
这样的断言按预期会失败,而无需引发错误:
expect(queryByText('Click me')).toBeInTheDocument();
expect(queryByLabel('Name').value).toBe('George')
如果找不到元素,抛出错误有什么好处?是否有理由不对所有(同步)查询使用queryBy
?
答案 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 *错误输出有两个优点:
这些边际开发经验的改进值得使用getBy *品种作为我的默认值。通常,我只在测试中使用getBy *,而在断言不存在某些重要内容时仅使用queryBy *。当然也可以只使用queryBy *,如果您发现同时使用两者的成本超过收益,则可以自由使用。