我有一个React组件。我用Jest作为跑步者编写测试,并编写测试库来编写测试。
注册组件代码(使用物化进行样式设计)是:
import React, { useState } from "react";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import Icon from "@material-ui/core/Icon";
import { makeStyles } from "@material-ui/core/styles";
import { create } from "./api-user.js";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import { Link } from "react-router-dom";
const useStyles = makeStyles((theme) => ({
card: {
maxWidth: 600,
margin: "auto",
textAlign: "center",
marginTop: theme.spacing(5),
paddingBottom: theme.spacing(2),
},
error: {
verticalAlign: "middle",
},
title: {
marginTop: theme.spacing(2),
color: theme.palette.openTitle,
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 300,
},
submit: {
margin: "auto",
marginBottom: theme.spacing(2),
},
}));
export default function Signup() {
const classes = useStyles();
const [values, setValues] = useState({
name: "",
password: "",
email: "",
open: false,
error: "",
});
const handleChange = (name) => (event) => {
setValues({ ...values, [name]: event.target.value });
};
const clickSubmit = () => {
const user = {
name: values.name || undefined,
email: values.email || undefined,
password: values.password || undefined,
};
create(user).then((data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({ ...values, error: "", open: true });
}
});
};
return (
<div>
<Card className={classes.card}>
<CardContent>
<Typography variant="h6" className={classes.title}>
Sign Up
</Typography>
<TextField
role="name"
id="name"
label="Name"
className={classes.textField}
value={values.name}
onChange={handleChange("name")}
margin="normal"
/>
<br />
<TextField
role="email"
id="email"
type="email"
label="Email"
className={classes.textField}
value={values.email}
onChange={handleChange("email")}
margin="normal"
/>
<br />
<TextField
role="password"
id="password"
type="password"
label="Password"
className={classes.textField}
value={values.password}
onChange={handleChange("password")}
margin="normal"
/>
<br />{" "}
{values.error && (
<Typography component="p" color="error">
<Icon color="error" className={classes.error}>
error
</Icon>
{values.error}
</Typography>
)}
</CardContent>
<CardActions>
<Button
color="primary"
variant="contained"
onClick={clickSubmit}
className={classes.submit}
>
Submit
</Button>
</CardActions>
</Card>
<Dialog open={values.open} disableBackdropClick={true}>
<DialogTitle>New Account</DialogTitle>
<DialogContent>
<DialogContentText>
New account successfully created.
</DialogContentText>
</DialogContent>
<DialogActions>
<Link to="/signin">
<Button color="primary" autoFocus="autoFocus" variant="contained">
Sign In
</Button>
</Link>
</DialogActions>
</Dialog>
</div>
);
}我正在尝试呈现组件,然后验证表单是否有Name、Email和Password输入。测试文件如下所示:
import React from "react";
import { screen, render, cleanup, fireEvent } from "@testing-library/react";
import SignUp from "./Signup";
describe("App component", () => {
beforeAll(() => {
render(<SignUp />);
});
it("should have the input field for name", () => {
const nameInput = screen.getByLabelText("Name");
expect(nameInput).toBeInTheDocument();
});
it("should have the input field for email", () => {
const emailInput = screen.getByLabelText("Email");
expect(emailInput).toBeInTheDocument();
});
it("should have the input field for password", () => {
const passwordInput = screen.getByLabelText("Password");
expect(passwordInput).toBeInTheDocument();
});
afterAll(cleanup);
});问题:无论我测试输入的顺序如何,第一个用例/测试总是通过的。.getByLabelText查询能够找到第一个it块的组件,并在下一个it块中失败。
运行上述文件测试的消息是:
FAIL client/user/SignUp.test.js
App component
✓ should have the input field for name (13 ms)
✕ should have the input field for email (3 ms)
✕ should have the input field for password (1 ms)
● App component › should have the input field for email
TestingLibraryElementError: Unable to find a label with the text of: Email
Ignored nodes: comments, script, style
<body />
12 | });
13 | it("should have the input field for email", () => {
> 14 | const emailInput = screen.getByLabelText("Email");
| ^
15 | expect(emailInput).toBeInTheDocument();
16 | });
17 | it("should have the input field for password", () => {
at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:40:19)
at getAllByLabelText (node_modules/@testing-library/dom/dist/queries/label-text.js:116:38)
at node_modules/@testing-library/dom/dist/query-helpers.js:62:17
at node_modules/@testing-library/dom/dist/query-helpers.js:111:19
at Object.getByLabelText (client/user/SignUp.test.js:14:31)
● App component › should have the input field for password当我把命令转到:
it("should have the input field for email", () => {
const emailInput = screen.getByLabelText("Email");
expect(emailInput).toBeInTheDocument();
});
it("should have the input field for name", () => {
const nameInput = screen.getByLabelText("Name");
expect(nameInput).toBeInTheDocument();
});
it("should have the input field for password", () => {
const passwordInput = screen.getByLabelText("Password");
expect(passwordInput).toBeInTheDocument();
});消息更改为:
FAIL client/user/SignUp.test.js
App component
✓ should have the input field for email (19 ms)
✕ should have the input field for name (8 ms)
✕ should have the input field for password (6 ms)
● App component › should have the input field for name
TestingLibraryElementError: Unable to find a label with the text of: Name
Ignored nodes: comments, script, style
<body />
13 | });
14 | it("should have the input field for name", () => {
> 15 | const nameInput = screen.getByLabelText("Name");
| ^
16 | expect(nameInput).toBeInTheDocument();
17 | });
18 | it("should have the input field for password", () => {
at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:40:19)
at getAllByLabelText (node_modules/@testing-library/dom/dist/queries/label-text.js:116:38)
at node_modules/@testing-library/dom/dist/query-helpers.js:62:17
at node_modules/@testing-library/dom/dist/query-helpers.js:111:19
at Object.getByLabelText (client/user/SignUp.test.js:15:30)
● App component › should have the input field for password
TestingLibraryElementError: Unable to find a label with the text of: Password
Ignored nodes: comments, script, style
<body />
17 | });
18 | it("should have the input field for password", () => {
> 19 | const passwordInput = screen.getByLabelText("Password");
| ^
20 | expect(passwordInput).toBeInTheDocument();
21 | });
22 | afterAll(cleanup);
at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:40:19)
at getAllByLabelText (node_modules/@testing-library/dom/dist/queries/label-text.js:116:38)
at node_modules/@testing-library/dom/dist/query-helpers.js:62:17
at node_modules/@testing-library/dom/dist/query-helpers.js:111:19
at Object.getByLabelText (client/user/SignUp.test.js:19:34) 正如您现在所看到的,对email的查询相对于其他2(name和email)有效。
更有趣的是,当我在一个it块中使用所有3个查询时,所有测试都通过了:
it("should have the input field for name", () => {
const nameInput = screen.getByLabelText("Name");
expect(nameInput).toBeInTheDocument();
const emailInput = screen.getByLabelText("Email");
expect(emailInput).toBeInTheDocument();
const passwordInput = screen.getByLabelText("Password");
expect(passwordInput).toBeInTheDocument();
}); 它验证了所有3个查询,您可以通过将参数更改为查询来测试它(SodeSandBox:https://codesandbox.io/s/react-testing-library-material-ui-select-forked-5rixw3?file=/src/App.test.js:254-891),如果您将它更改为像const emailInput = screen.getByLabelText("Email-failing");一样,它将失败。
有人能告诉我,为什么测试库在同一个块中工作,而不是在单独的块中工作?我如何测试三个输入?我还尝试过不同的查询方法,例如角色属性的.getByRole,它的行为方式是相同的,即在单个块中工作,而第2和第3块/测试失败。
发布于 2022-11-16 13:54:30
在进行所有测试之前,您将呈现组件。相反,您应该在每个测试中呈现组件。不要在beforeAll块中使用呈现,在每个' it‘块中使用它。
import React from "react";
import { screen, render, cleanup, fireEvent } from "@testing-
library/react";
import SignUp from "./Signup";
describe("App component", () => {
it("should have the input field for name", () => {
render(<SignUp />);
const nameInput = screen.getByLabelText("Name");
expect(nameInput).toBeInTheDocument();
});
it("should have the input field for email", () => {
render(<SignUp />);
const emailInput = screen.getByLabelText("Email");
expect(emailInput).toBeInTheDocument();
});
it("should have the input field for password", () => {
render(<SignUp />);
const passwordInput = screen.getByLabelText("Password");
expect(passwordInput).toBeInTheDocument();
});
afterAll(cleanup);
});https://stackoverflow.com/questions/74461629
复制相似问题