React 测试库:我是否需要为每个测试键使用新选择器进行新测试?
React Testing Library: Do I need a new test with new selectors for each test key?
我正在使用 React 测试库构建一个带有 TDD 的 React 应用程序。
TLDR: 选择器(例如 toBeInTheDocument()
)似乎只在 render
之后工作一次。是吗?
我使用 CRA 制作了应用,这是我的 src/setupTests.js
:
// react-testing-library renders your components to document.body,
// this will ensure they're removed after each test.
import "react-testing-library/cleanup-after-each";
// this adds jest-dom's custom assertions
import "jest-dom/extend-expect";
这是我写的测试:
import { pluck } from "ramda";
import React from "react";
import { render } from "react-testing-library";
import ContactList from "../components/ContactList";
import { contacts } from "../fixtures";
describe("Contact List", () => {
describe("given no contacts", () => {
const { getByText } = render(<ContactList />);
it("displays 'First Name' in the header", () => {
const actual = getByText(/first name/i);
expect(actual).toBeInTheDocument();
});
it("displays 'Last Name' in the header", () => {
const actual = getByText(/last name/i);
expect(actual).toBeInTheDocument();
});
it("displays 'No Contacts'", () => {
const actual = getByText(/no contacts/i);
expect(actual).toBeInTheDocument();
});
});
describe("given a list of contacts", () => {
const props = { contacts };
const { getAllByTestId } = render(<ContactList {...props} />);
it("displays the first name of all contacts", () => {
const actual = pluck("textContent")(getAllByTestId("contact-first-name"));
const expected = pluck("firstName")(contacts);
expect(actual).toEqual(expected);
});
it("displays the last name of all contacts", () => {
const actual = pluck("textContent")(getAllByTestId("contact-last-name"));
const expected = pluck("lastName")(contacts);
expect(actual).toEqual(expected);
});
});
});
这是我写的组件:
import React from "react";
import PropTypes from "prop-types";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import withStyles from "@material-ui/core/styles/withStyles";
import strings from "../strings";
function ContactList({ contacts }) {
const renderContact = ({ firstName = "N/A", lastName = "N/A", id }) => (
<TableRow key={id}>
<TableCell data-testid="contact-first-name">{firstName}</TableCell>
<TableCell data-testid="contact-last-name">{lastName}</TableCell>
</TableRow>
);
return (
<Table>
<TableHead>
<TableRow>
<TableCell>{strings.firstName}</TableCell>
<TableCell>{strings.lastName}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{contacts.length > 0 ? (
contacts.map(renderContact)
) : (
<TableRow>
<TableCell>{strings.noContacts}</TableCell>
</TableRow>
)}
</TableBody>
</Table>
);
}
ContactList.propTypes = {
classes: PropTypes.object.isRequired,
contacts: PropTypes.arrayOf(
PropTypes.shape({
firstName: PropTypes.string.isRequired,
lastName: PropTypes.string.isRequired
})
).isRequired
};
ContactList.defaultProps = {
contacts: []
};
const styles = {};
export default withStyles(styles)(ContactList);
现在,如果我 运行 这些测试,每个 describe
块只有前两个通过。
例如,如果我给任何 it
测试一个 .only
它通过了。
这是怎么回事?我不能为多个断言重用相同的测试设置吗?我是否必须为每个 it
调用 render
?
您正在导入 react-testing-library/cleanup-after-each
,这会在每次测试后删除渲染的组件。这是正确的方法,但是您应该在每个 it
块中渲染组件。
我正在使用 React 测试库构建一个带有 TDD 的 React 应用程序。
TLDR: 选择器(例如 toBeInTheDocument()
)似乎只在 render
之后工作一次。是吗?
我使用 CRA 制作了应用,这是我的 src/setupTests.js
:
// react-testing-library renders your components to document.body,
// this will ensure they're removed after each test.
import "react-testing-library/cleanup-after-each";
// this adds jest-dom's custom assertions
import "jest-dom/extend-expect";
这是我写的测试:
import { pluck } from "ramda";
import React from "react";
import { render } from "react-testing-library";
import ContactList from "../components/ContactList";
import { contacts } from "../fixtures";
describe("Contact List", () => {
describe("given no contacts", () => {
const { getByText } = render(<ContactList />);
it("displays 'First Name' in the header", () => {
const actual = getByText(/first name/i);
expect(actual).toBeInTheDocument();
});
it("displays 'Last Name' in the header", () => {
const actual = getByText(/last name/i);
expect(actual).toBeInTheDocument();
});
it("displays 'No Contacts'", () => {
const actual = getByText(/no contacts/i);
expect(actual).toBeInTheDocument();
});
});
describe("given a list of contacts", () => {
const props = { contacts };
const { getAllByTestId } = render(<ContactList {...props} />);
it("displays the first name of all contacts", () => {
const actual = pluck("textContent")(getAllByTestId("contact-first-name"));
const expected = pluck("firstName")(contacts);
expect(actual).toEqual(expected);
});
it("displays the last name of all contacts", () => {
const actual = pluck("textContent")(getAllByTestId("contact-last-name"));
const expected = pluck("lastName")(contacts);
expect(actual).toEqual(expected);
});
});
});
这是我写的组件:
import React from "react";
import PropTypes from "prop-types";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import withStyles from "@material-ui/core/styles/withStyles";
import strings from "../strings";
function ContactList({ contacts }) {
const renderContact = ({ firstName = "N/A", lastName = "N/A", id }) => (
<TableRow key={id}>
<TableCell data-testid="contact-first-name">{firstName}</TableCell>
<TableCell data-testid="contact-last-name">{lastName}</TableCell>
</TableRow>
);
return (
<Table>
<TableHead>
<TableRow>
<TableCell>{strings.firstName}</TableCell>
<TableCell>{strings.lastName}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{contacts.length > 0 ? (
contacts.map(renderContact)
) : (
<TableRow>
<TableCell>{strings.noContacts}</TableCell>
</TableRow>
)}
</TableBody>
</Table>
);
}
ContactList.propTypes = {
classes: PropTypes.object.isRequired,
contacts: PropTypes.arrayOf(
PropTypes.shape({
firstName: PropTypes.string.isRequired,
lastName: PropTypes.string.isRequired
})
).isRequired
};
ContactList.defaultProps = {
contacts: []
};
const styles = {};
export default withStyles(styles)(ContactList);
现在,如果我 运行 这些测试,每个 describe
块只有前两个通过。
例如,如果我给任何 it
测试一个 .only
它通过了。
这是怎么回事?我不能为多个断言重用相同的测试设置吗?我是否必须为每个 it
调用 render
?
您正在导入 react-testing-library/cleanup-after-each
,这会在每次测试后删除渲染的组件。这是正确的方法,但是您应该在每个 it
块中渲染组件。