当执行同一组件的两个渲染时,按钮禁用属性未正确更新
Button disabled attribute is not updated correctly when two renders of the same component are performed
我刚开始使用 react-testing-library,所以我猜测这最终归结为用户错误,但我看到以下行为对我来说没有意义。
在新创建的 CRA 应用程序中使用 jest-dom 3.0.0 和 react-testing-library 5.4.4 进行以下测试 运行:
import React from "react";
import { render } from "react-testing-library";
import "jest-dom/extend-expect";
import Component from "./Component";
describe("Verify UI state based on jobs", () => {
it("mounts with no previous data", () => {
const { getByTestId } = render(<Component data={[]} />);
expect(getByTestId("refresh-button")).toBeDisabled();
});
it("mounts with previous data", () => {
const { getByTestId } = render(<Component data={["hi"]} />);
expect(getByTestId("refresh-button")).not.toBeDisabled();
});
});
/*
const Component = props => {
return (
<div>
<button data-testid="refresh-button" disabled={props.data.length === 0}>
Refresh
</button>
</div>
);
};
*/
事实上,我遇到了以下故障:
根据作业验证 UI 状态 › 使用以前的数据装载
expect(element).not.toBeDisabled()
Received element is disabled:
<button data-testid="refresh-button" disabled="" />
13 | it("mounts with previous data", async () => {
14 | const { getByTestId } = render(<Component data={["hi"]} />);
> 15 | expect(getByTestId("refresh-button")).not.toBeDisabled();
| ^
16 | });
17 | });
18 |
at Object.toBeDisabled (src/Component.test.js:15:47)
但是,如果我禁用第一个测试,第二个测试现在会正常通过。如果我重新排序,第一个测试总是通过而第二个总是失败,即使第一个测试是 'mount with pervious data' 测试。
不确定这是否是测试库、jest-dom 或我的代码中的问题,但如有任何关于如何正确构建这些测试的建议,我们将不胜感激。
文档当前声明当 render
is called "the queries from dom-testing-library
are automatically returned with their first argument bound to the rendered container".
事实证明这是文档中的一个错误,因为如果没有 container
传递给 render
,查询实际上绑定到 document.body
(代码 here and here ).
react-testing-library
使用 DOM,除非在测试之间调用 cleanup
,否则来自早期测试的 DOM 元素仍将存在,并将包含在以后的查询结果中.
在这种情况下,在第二次测试期间,Component
元素都存在于 document.body
中,并且由于 getByTestId
查询 document.body
它最终找到了这两个元素,并且当它找到时不止一个吧returns the first one it finds.
这意味着第一个测试的 Component
在第二个测试中被 getByTestId
返回,这导致测试失败,因为第一个组件被禁用。
要解决此问题,请确保在每次测试后调用 cleanup
以删除在之前测试期间添加的所有 DOM 元素:
import React from "react";
import { render, cleanup } from "react-testing-library";
import "jest-dom/extend-expect";
afterEach(cleanup); // clean up the DOM after each test
describe("Verify UI state based on jobs", () => {
it("mounts with no previous data", () => {
const { getByTestId } = render(<Component data={[]} />);
expect(getByTestId("refresh-button")).toBeDisabled(); // SUCCESS
});
it("mounts with previous data", () => {
const { getByTestId } = render(<Component data={["hi"]} />);
expect(getByTestId("refresh-button")).not.toBeDisabled(); // SUCCESS
});
});
我刚开始使用 react-testing-library,所以我猜测这最终归结为用户错误,但我看到以下行为对我来说没有意义。
在新创建的 CRA 应用程序中使用 jest-dom 3.0.0 和 react-testing-library 5.4.4 进行以下测试 运行:
import React from "react";
import { render } from "react-testing-library";
import "jest-dom/extend-expect";
import Component from "./Component";
describe("Verify UI state based on jobs", () => {
it("mounts with no previous data", () => {
const { getByTestId } = render(<Component data={[]} />);
expect(getByTestId("refresh-button")).toBeDisabled();
});
it("mounts with previous data", () => {
const { getByTestId } = render(<Component data={["hi"]} />);
expect(getByTestId("refresh-button")).not.toBeDisabled();
});
});
/*
const Component = props => {
return (
<div>
<button data-testid="refresh-button" disabled={props.data.length === 0}>
Refresh
</button>
</div>
);
};
*/
事实上,我遇到了以下故障:
根据作业验证 UI 状态 › 使用以前的数据装载
expect(element).not.toBeDisabled()
Received element is disabled:
<button data-testid="refresh-button" disabled="" />
13 | it("mounts with previous data", async () => {
14 | const { getByTestId } = render(<Component data={["hi"]} />);
> 15 | expect(getByTestId("refresh-button")).not.toBeDisabled();
| ^
16 | });
17 | });
18 |
at Object.toBeDisabled (src/Component.test.js:15:47)
但是,如果我禁用第一个测试,第二个测试现在会正常通过。如果我重新排序,第一个测试总是通过而第二个总是失败,即使第一个测试是 'mount with pervious data' 测试。
不确定这是否是测试库、jest-dom 或我的代码中的问题,但如有任何关于如何正确构建这些测试的建议,我们将不胜感激。
文档当前声明当 render
is called "the queries from dom-testing-library
are automatically returned with their first argument bound to the rendered container".
事实证明这是文档中的一个错误,因为如果没有 container
传递给 render
,查询实际上绑定到 document.body
(代码 here and here ).
react-testing-library
使用 DOM,除非在测试之间调用 cleanup
,否则来自早期测试的 DOM 元素仍将存在,并将包含在以后的查询结果中.
在这种情况下,在第二次测试期间,Component
元素都存在于 document.body
中,并且由于 getByTestId
查询 document.body
它最终找到了这两个元素,并且当它找到时不止一个吧returns the first one it finds.
这意味着第一个测试的 Component
在第二个测试中被 getByTestId
返回,这导致测试失败,因为第一个组件被禁用。
要解决此问题,请确保在每次测试后调用 cleanup
以删除在之前测试期间添加的所有 DOM 元素:
import React from "react";
import { render, cleanup } from "react-testing-library";
import "jest-dom/extend-expect";
afterEach(cleanup); // clean up the DOM after each test
describe("Verify UI state based on jobs", () => {
it("mounts with no previous data", () => {
const { getByTestId } = render(<Component data={[]} />);
expect(getByTestId("refresh-button")).toBeDisabled(); // SUCCESS
});
it("mounts with previous data", () => {
const { getByTestId } = render(<Component data={["hi"]} />);
expect(getByTestId("refresh-button")).not.toBeDisabled(); // SUCCESS
});
});