Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
439 views
in Technique[技术] by (71.8m points)

reactjs - Jest/Enzyme: Mock function in Functional Component

I have a functional component in React. Here is the code

import React, { useState, Fragment } from "react";
import { makeStyles } from "@material-ui/core/styles";
import "./K8sIPCalculator.css";
import { initialState, checkBoxLabel } from "./FormMetaData";
import { checkPositiveInteger } from "./FormDataValidation";

const useStyles = makeStyles((theme) => ({
  // Styles
}));

const K8sIPCalculator = (props) => {
  const classes = useStyles();
  let intialStateCopy = JSON.parse(JSON.stringify(initialState));
  const [data, setData] = useState(intialStateCopy);

  const handleCheckBox = (path, value) => {
    const newData = { ...data };
    if (path === "nodes" || path === "pods") {
      if (!checkPositiveInteger(value)) {
        newData[path].value = value;
        newData[path].helperText = "It should be a positive integer!";
      } else {
        newData[path].value = value;
        newData[path].helperText = "";
      }
    } else newData[path] = value;
    setData(newData);
  };

  const calculate = () => {
           // Does some calculation and update data state
  };

  const onSubmit = () => {
    if (data.nodes.helperText !== "" || data.pods.helperText !== "") {
      alert("Data is not correct");
      return;
    }
    calculate();
  };

  const onReset = () => {
    intialStateCopy = JSON.parse(JSON.stringify(initialState));
    setData(intialStateCopy);
  };

  return (
    <Fragment>
      <h2 className="name">K8s IP Calculator</h2>
      <form className={classes.formRoot}>
        <Accordion
          defaultExpanded={true}
          classes={{ expanded: classes.expanded }}
        >
          <AccordionSummary
            expandIcon={<ExpandMoreIcon />}
            id="accordion1"
            className={classes.summary}
          >
            <Typography className={classes.heading}>Results</Typography>
          </AccordionSummary>
          <AccordionDetails className="container">
            <InputLabel className={classes.label}>
              Total useable IPs required:
            </InputLabel>
            <TextField
              disabled
              className={classes.textDisabledInput}
              id="ips-required-output"
              variant="outlined"
              value={data.total}
            />
            <InputLabel className={classes.label} htmlFor="subnet-size-output">
              Subnet Size required:
            </InputLabel>
            <TextField
              disabled
              className={classes.textDisabledInput}
              id="subnet-size-output"
              variant="outlined"
              value={data.subnet_size}
            />
          </AccordionDetails>
        </Accordion>
        <br />
        <Accordion
          defaultExpanded={true}
          classes={{ expanded: classes.expanded }}
        >
          <AccordionSummary
            expandIcon={<ExpandMoreIcon />}
            id="accordion2"
            className={classes.summary}
          >
            <Typography className={classes.heading}>K8s Details</Typography>
          </AccordionSummary>
          <AccordionDetails className="container">
            <InputLabel className={classes.label}>Nodes:</InputLabel>
            <TextField
              size="small"
              type="number"
              onChange={(e) => handleCheckBox("nodes", e.target.value)}
              className={classes.textInput}
              id="nodes-input"
              variant="outlined"
              value={data.nodes.value}
              helperText={data.nodes.helperText}
            />
            <InputLabel className={classes.label} htmlFor="pods-input">
              Pods:
            </InputLabel>
            <TextField
              size="small"
              type="number"
              onChange={(e) => handleCheckBox("pods", e.target.value)}
              className={classes.textInput}
              id="pods-input"
              variant="outlined"
              value={data.pods.value}
              helperText={data.pods.helperText}
            />
            <div id="nodes-error"></div>
          </AccordionDetails>
        </Accordion>
        <div className="button-container">
          <Button
            id="reset-button"
            className="button"
            variant="outlined"
            color="primary"
            size="small"
            onClick={onReset}
            startIcon={<UndoIcon />}
          >
            Reset
          </Button>
          <Button
            id="submit-button"
            className="button"
            variant="contained"
            color="primary"
            size="small"
            startIcon={<SaveIcon />}
            onClick={onSubmit}
          >
            Submit
          </Button>
        </div>
      </form>
    </Fragment>
  );
};

export default K8sIPCalculator;


Things, I am trying to test,

  1. When input changes, I want to check if handleCheckBox function has been called
  2. When submit button is called, I want to check if calculate function has been called
  3. How can I call the setData function to update data through Jest/Enzyme

I tried something like this

const spy = jest.spyOn(K8sIPCalculator, "calculate");

But I got

Cannot spy the calculate property because it is not a function; undefined given instead

PS: I am able to assert data change after submit is called. But I want to check if calculate function is called.

    const submit = wrapper.find("button#submit-button");
    submit.simulate("click");

    expect(wrapper.find("input#ips-required-output").props().value).toEqual(35);
    expect(wrapper.find("input#subnet-size-output").props().value).toEqual(
      "/26"
    );
question from:https://stackoverflow.com/questions/66062057/jest-enzyme-mock-function-in-functional-component

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...