I find myself in a very unique situation because every blog I have been to says that I should not be having the issue with enzyme + jest that I am having. I am using react 16.8.5 to put together a small application. In that application I have the following code of a functional component that uses hooks
const allDaSums = (props) => {
const [inputStateVal, setInputStateVal] = useState("");
const [inputNumArray, setInputNumArray] = useState([0]);
const [exception, setException] = useState("")
const [result, setResult ] = useState(null);
const createNumArray = () => {
//code generating zeroArray and also positiveNumberArray
//more code that also sets exception using SetException from above
const positiveNumberArray = numberOnlyArray.filter(n => n > 0)
setInputNumArray([...positiveNumberArray, ...zeroArray]);
}
const evaluateSum = () => {
// code doing math things and produce result
setResult(reduceResult);
}
const styleResult = () => {
return <span id={"resultElement"} className={classes.Result}>{result}</span>;
}
return(
<React.Fragment>
<div className={classes.CalculatorUIContainer}>
<input
className={exception.length ? classes.CalculatorInputException : classes.CalculatorInput}
value={inputStateVal}
onChange={(e) => setInputStateVal(e.target.value)}
onBlur={createNumArray}
id={"inputVals"}
placeholder={placeHolderText ? placeHolderText : "Input comma separated numbers"} />
<Button
id={"calculateButton"}
type={"button"}
btnType={"Success"}
clicked={evaluateSum}
>Calculate</Button>
</div>
{result !== null && !exception.length ?
<div id={"resultDiv"} className={classes.ResultAnnouncement}>The sum of the values is: {styleResult()}</div>
:
null
}
{exception.length ?
<div id={"exceptionElement"} className={classes.Exception}>{exception}</div>
:
null
}
</React.Fragment>
)
}
the above is a condensed version of my functional component. Then in my app, created using create-react-app script and ejected, I have a folder called test and inside I have my test file with the following breaking test
import React from 'react';
import { shallow, mount} from 'enzyme'
import AllDaSums from '../../src/containers/AllDaSums/AllDaSums';
describe("Inputing values", () => {
it('values are entered into the input field and state updates', () => {
const wrapper = shallow(<AllDaSums />);
// wrapper.find("input").simulate('change', { target: { value: '1,2' } });
wrapper.find("input").prop('onChange')({
target: {
value: '1,2'
}
});
wrapper.find(Button).simulate("click");
wrapper.update();
expect(wrapper.find('#resultDiv')).toHaveLength(1)
console.log(wrapper.debug())
});
});
current my test fails with the following error
● Inputing values › values are entered into the input field and state updates
expect(received).toHaveLength(expected)
Expected length: 1
Received length: 0
Received object: {}
and the console.log shows the following
console.log test/StringCalculator.test.js:38
<Fragment>
<div className={[undefined]}>
<input className={[undefined]} type="text" value="1,2" onChange={[Function: onChange]} onBlur={[Function: createNumArray]} id="inputVals" />
<button id="calculateButton"clicked={[Function: evaluateSum]}>
Calculate
</button>
</div>
</Fragment>
what I can't seem to figure out is why the simulated click is not causing a new render thus updating the result variable and thus rendering the jsx that shows the result.
Here are my devDependencies
"devDependencies": {
"babel-preset-env": "^1.7.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"babel-preset-react-app": "^7.0.0"
}
and I have a test folder with my test file in it as well as a jest.config.js file with the following:
module.exports = {
setupFiles: [
'<rootDir>/test/setupTests.js',
],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/test/styleMock.js',
}
};
So might anyone know what I am doing wrong or what is causing my test to fail when it, I think, obviously shouldn't?
PS I have also tried the react-testing-library endorsed by THE Kent C. Dodds but that also doesn't cause a rerender thus the result dependent jsx doesn't show up on the page when I search for it.
PSS Using mount instead of shallow gives me this error
● Inputing values › values are entered into the input field and state updates
TypeError: Cannot read property 'current' of undefined
I think I found a solution but maybe not the most ideal solution. So if anyone can think of a cleaner one, please don't be shy.
My new working test now looks like this
it('values are entered into the input field, button is clicked, and result is shown', () => {
const wrapper = shallow(<StringCalculator />);
wrapper.find("input").simulate('change', { target: { value: '1,2' } });
wrapper.find("#inputVals").props().onBlur();
wrapper.find(Button).props().clicked();
expect(wrapper.find('#resultDiv').exists()).toEqual(true)
expect(wrapper.find('#resultElement').text()).toEqual('3')
});
});
I think this should work perfectly fine with @testing-library/react
Note : testing-library
is by default configured to pick your elements by data-testid
so you need to use data-testid
instead of just id
. However you can configure this to refer id
as well.
import React from "react";
import { render, fireEvent } from "@testing-library/react";
// import AllDaSums -- your component
it("render test", () => {
const { getByTestId } = render(<AllDaSums />);
fireEvent.change(getByTestId("inputVals"), { target: { value: "1,2" } });
fireEvent.click(getByTestId("calculateButton"));
expect(getByTestId("resultDiv").textContent).toBe(
"The sum of the values is: 3"
);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.