我对反应和测试都是全新的,有点困惑。 我只是想知道是否有人可以告诉我为什么我的测试失败。我认为我在如何工作上犯了一个基本错误。 我正在尝试测试登录页面。目前,我只是想进行测试以触发按钮的onclick并检查是否已调用函数。
登录组件代码如下。
import React, { Component, Fragment } from "react";
import { Redirect } from "react-router-dom";
// Resources
//import logo from "assets/img/white-logo.png";
//import "./Login.css";
// Material UI
import {
withStyles,
MuiThemeProvider,
createMuiTheme
} from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Person from "@material-ui/icons/Person";
import InputAdornment from "@material-ui/core/InputAdornment";
// Custom Components
import Loading from "components/Loading/Loading.jsx";
// bootstrat 1.0
import { Alert, Row } from "react-bootstrap";
// MUI Icons
import LockOpen from "@material-ui/icons/LockOpen";
// remove
import axios from "axios";
// API
import api2 from "../../helpers/api2";
const styles = theme => ({
icon: {
color: "#fff"
},
cssUnderline: {
color: "#fff",
borderBottom: "#fff",
borderBottomColor: "#fff",
"&:after": {
borderBottomColor: "#fff",
borderBottom: "#fff"
},
"&:before": {
borderBottomColor: "#fff",
borderBottom: "#fff"
}
}
});
const theme = createMuiTheme({
palette: {
primary: { main: "#fff" }
}
});
class Login extends Component {
constructor(props, context) {
super(props, context);
this.state = {
username: "",
password: "",
isAuthenticated: false,
error: false,
toggle: true,
// loading
loading: false
};
}
openLoading = () => {
this.setState({ loading: true });
};
stopLoading = () => {
this.setState({ loading: false });
};
toggleMode = () => {
this.setState({ toggle: !this.state.toggle });
};
handleReset = e => {
const { username } = this.state;
this.openLoading();
api2
.post("auth/admin/forgotPassword", { email: username })
.then(resp => {
this.stopLoading();
console.log(resp);
})
.catch(error => {
this.stopLoading();
console.error(error);
});
};
handleSubmit = event => {
event.preventDefault();
localStorage.clear();
const cred = {
username: this.state.username,
password: this.state.password
};
api2
.post("auth/admin", cred)
.then(resp => {
console.log(resp);
localStorage.setItem("api_key", resp.data.api_key);
localStorage.setItem("username", cred.username);
return this.setState({ isAuthenticated: true });
})
.catch(error => {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error", error.message);
}
console.log(error.config);
return this.setState({ error: true });
});
};
handleInputChange = event => {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
};
forgotPassword = () => {
console.log("object");
};
render() {
const { error } = this.state;
const { isAuthenticated } = this.state;
const { classes } = this.props;
if (isAuthenticated) {
return <Redirect to="/home/dashboard" />;
}
return (
<div className="login-page">
<video autoPlay muted loop id="myVideo">
<source
src=""
type="video/mp4"
/>
</video>
<div className="videoOver" />
<div className="midl">
<Row className="d-flex justify-content-center">
<img src={''} className="Login-logo" alt="logo" />
</Row>
<br />
<Row className="d-flex justify-content-center">
{error && (
<Alert style={{ color: "#fff" }}>
The username/password entered is incorrect. Try again!
</Alert>
)}
</Row>
<MuiThemeProvider theme={theme}>
<Row className="d-flex justify-content-center">
<TextField
id="input-username"
name="username"
type="text"
label="username"
value={this.state.username}
onChange={this.handleInputChange}
InputProps={{
className: classes.icon,
startAdornment: (
<InputAdornment position="start">
<Person className={classes.icon} />
</InputAdornment>
)
}}
/>
</Row>
{this.state.toggle ? (
<Fragment>
<br />
<Row className="d-flex justify-content-center">
<TextField
id="input-password"
name="password"
type="password"
label="pasword"
value={this.state.password}
onChange={this.handleInputChange}
className={classes.cssUnderline}
InputProps={{
className: classes.icon,
startAdornment: (
<InputAdornment position="start">
<LockOpen className={classes.icon} />
</InputAdornment>
)
}}
/>
</Row>
</Fragment>
) : (
""
)}
</MuiThemeProvider>
<br />
<Row className="d-flex justify-content-center">
{this.state.toggle ? (
<Button
className="button login-button"
data-testid='submit'
type="submit"
variant="contained"
color="primary"
onClick={this.handleSubmit}
name = "logIn"
>
Login
</Button>
) : (
<Button
className="button login-button"
type="submit"
variant="contained"
color="primary"
onClick={this.handleReset}
>
Reset
</Button>
)}
</Row>
<Row className="d-flex justify-content-center">
<p onClick={this.toggleMode} className="text-link">
{this.state.toggle ? "Forgot password?" : "Login"}
</p>
</Row>
</div>
<Loading open={this.state.loading} onClose={this.handleClose} />
</div>
);
}
}
export default withStyles(styles)(Login);
我当前的测试失败。
import React from 'react'
import {render, fireEvent, getByTestId} from 'react-testing-library'
import Login from './login'
describe('<MyComponent />', () => {
it('Function should be called once', () => {
const functionCalled = jest.fn()
const {getByTestId} = render(<Login handleSubmit={functionCalled} />)
const button = getByTestId('submit');
fireEvent.click(button);
expect(functionCalled).toHaveBeenCalledTimes(1)
});
});
答案 0 :(得分:0)
我也是React Testing Library的新手,但是看来您的按钮正在使用this.handleSubmit
,因此将模拟功能作为道具传递不会做任何事情。如果您要从某个容器中传递handleSubmit,那么我相信您目前的测试将通过。