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,
- When input changes, I want to check if handleCheckBox function has been called
- When submit button is called, I want to check if calculate function has been called
- 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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…