如前所述,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" } });
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*测试失败,这可能是我将要采取的第一步,所以它自动出现是很好的。