Javascript 反应测试库-避免getBy?
当使用React测试库测试组件时,我发现自己从Javascript 反应测试库-避免getBy?,javascript,reactjs,testing,jestjs,react-testing-library,Javascript,Reactjs,Testing,Jestjs,React Testing Library,当使用React测试库测试组件时,我发现自己从getBy*开始,偶尔需要将其替换为queryBy*(例如,如果我需要检查元素是否不存在)。我的测试结果是混合使用了getBy和queryBy,我最近一直在使用queryBy 这让我想。。。是否有理由使用getBy 像这样的断言会按预期失败,无需抛出错误: expect(queryByText('Click me')).toBeInTheDocument(); expect(queryByLabel('Name').value).toBe('Geor
getBy*
开始,偶尔需要将其替换为queryBy*
(例如,如果我需要检查元素是否不存在)。我的测试结果是混合使用了getBy
和queryBy
,我最近一直在使用queryBy
这让我想。。。是否有理由使用getBy
像这样的断言会按预期失败,无需抛出错误:
expect(queryByText('Click me')).toBeInTheDocument();
expect(queryByLabel('Name').value).toBe('George')
如果找不到元素,抛出错误有什么好处?对于所有(同步)查询,是否有理由不使用queryBy
EDIT:现在只推荐使用queryBy
来断言文档中没有某些内容:
本文还建议使用
screen.queryBy
/screen.getBy
而不是从render
解构,这简化了从一个到另一个的更改,因为您不再需要更新解构函数。如您所述,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" } });
无法通过以下方式找到元素:[data testid=“textInput”]
显示文本输入!
21 | const{getByTestId,queryByTestId,rerender}=render(getComponent());
22 |
>23 | const textInput=getByTestId(“textInput”),如有;
| ^
24 |
25 | firevent.change(textInput,{target:{value:{hello}});
26 | firevent.change(textInput,{target:{value:{hi}});
因此,在我看来,getBy*错误输出有两个优点:
这些边际开发体验的改进值得使用getBy*变体作为我的默认选项。通常,我在测试中只使用getBy*,在断言某些内容不存在很重要时,只使用queryBy*。当然,只使用queryBy*是有可能的,如果您发现使用这两种方法的成本大于好处,您可以自由地这样做。但是
queryBy*
在您期望有东西出现时效果非常好!如果它找不到任何内容,则在您尝试对其进行断言或访问属性时,它将失败,并显示一条指向根本问题的错误消息。然后,您不必同时对getBy
和queryBy
进行解构,也不必直接使用两个稍有不同的API。我只是还没有遇到过这样一种情况,即getBy
是比queryBy
更好的工具。添加了一个示例,尝试将getBy*
的优势具体化一点。对我来说,这些边际收益超过了您提到的保持两种不同API的正常运行的边际成本,但它们可能不适合您。这很有帮助!一般来说,消息无法触发“更改”事件-请提供一个DOM元素。
对我来说已经足够了,但是在使用getBy*
时打印DOM而不使用debug()。谢谢你周到的回答!