【问题标题】:Can't get jest test to fire button onclick无法在点击按钮时进行开玩笑测试
【发布时间】:2019-03-11 14:53:30
【问题描述】:

我对反应和测试都是全新的,有点难过。 我只是想知道是否有人可以告诉我为什么我的测试失败了。我认为我在这应该如何工作方面犯了一个基本错误。 我正在尝试测试登录页面。目前我只是想让我的测试从一个按钮触发一个 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)
    });
});

【问题讨论】:

    标签: reactjs unit-testing testing react-testing-library


    【解决方案1】:

    我对 React 测试库也很陌生,但看起来您的按钮正在使用 this.handleSubmit,因此将您的模拟函数作为道具传递不会做任何事情。如果您要从某个容器传入 handleSubmit,那么我相信您的测试(就像您目前拥有的那样)会通过。

    【讨论】:

    • 嗨,杰斯,感谢您的回答。从某个容器传入handlesubmit 是什么意思?
    • class LoginContainer { render{ return( &lt;Login handleSubmit={this.handleSubmit} /&gt; ) } } 之类的东西 因为您的组件没有接收该函数作为道具,所以无法对其进行测试。
    • 啊...您的意思是更改正在测试的代码。不幸的是,我无法做到这一点。
    • 本着 react-testing-library 的精神,您可以尝试测试一下 Login 按钮是否存在。比如:const { getByText, queryByText } = render(&lt;Login /&gt;); const button = getByText("submit"); expect(button).toBeDefined(); rerender(&lt;Login /&gt;); expect(queryByText("submit")).toBeNull(); expect(getByText("Reset")).toBeDefined();
    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多