Edit (2020): I would recommend switching over to react-testing-library, and changing your testing approach to test how your component changes with ...
For further actions, you may consider blocking this person and/or reporting abuse
This is super helpful, thank you. Can you shed any light on why importing
useState
:import React, { useState } from 'react'
and calling it on line 4 of FunctionalComponent.jsx as:
const [count, setCount] = useState(0)
breaks the test? Seems like the spy should still see that getting called?
Yup, so the issue is because we are spying on
React.useState
, which sets a spy on the default export from 'react'. Since you are pulling in useState as a named export, there is no spy on it.I've messed around with mocking the named export, but it's not super straight forward. I've always done it using
import * as Something from 'module';
, but I can't seem to get that to work with react.And if you mock the whole react module, you get some errors from enzyme.
Here are some of the sources I used when looking into this:
jest-mock-default-named-export
mock-spy-exported-functions-within...
If you can figure it out, please let me know because I'm very interested :)
But it seems that just calling useState from React is the easiest way. To be honest, I don't see the point in importing useState as a named export when it's already included in the default export.
Great, thanks. I'll play around with it - we're using useState as a named export all over the place - wouldn't be a HUGE deal to convert but it'd be nice to figure out how to test as-is.
Did you happen to find a solution?
to make it work with useState we would have to mock it using jest while keeping rest of react intact. jest.requireActual can be used to achieve that
The following technique works well for me testing functional components with
useState
destructured. This is an adapted solution from that above because the mockImplementation above caused react-test-renderer tests to fail:This is typescript, but it should work just as well in JS if you remove the type annotations
works fine for me
Thanks @Jonah, It works
How can we test this type of case with jest and enzyme?
const [open, setOpen] = useState(false);
const handleClose = () => {
setOpen(!open);
this handleClose is an onClick event
How about testing for a component with multiple
useState
s?Could you tell me how to detect each
setState
to be called?Hello,
Could you explain more exactly what does these do :
const setState = jest.fn();
const useStateSpy = jest.spyOn(React, 'useState')
useStateSpy.mockImplementation((init) => [init, setState]);
Hi, thanks for sharing the tutorial! However, things might still not work for me, and I am not sure how did
useStateSpy
connected with theEnzyme.shallow(<TestComponent />);
in your test case...In addition, my
wrapper
byshallow
turns out to benull
, but when I usemount
it can show me correct component.How do you make this work when you set the state inside a useEffect?
For me it doesn't see the mocked setState function...
If you guys wants a way that gives you full access to your react hooks's states and dispatchers without the pain to extract or modify your code.
You can use my library: github.com/victor95pc/jest-react-h...
I am getting following error after npm install.
how to get init state not using library ?
IMHO your approach is legit but describes a creation of
brittle
tests - you are trying to test implementation and not the behaviour: if you decide to eventually change implementation (use class component and the real setState method on it), your test will fail and you will have to adjust it accordingly, which should be avoided. On the other hand, I do not propose a solution, because Enzyme does not propose it - they still have to catch up with hooks. One may consider switching to React Testing Library if the hooks in the app are used extensively (I recently realised that there is no need for class components any longer given the hooks have been introduced a year ago) - it has much better support for hooks and is a React-recommended testing library. If, on the other hand, it is an application that extensively uses class components, then, I guess, one should not switch to hooks for the sake of having Enzyme continue a good job of testing the state values and not their implementation.P.S. Actually testing a state in general is a bad idea - it is better to test what is being rendered, thereby completely focusing on the result and not implementation details, as well as making my above comments valid but obsolete and the problem non-existent :-)
Testing state change with hooks,
How to test init state ??
describe('init value, () => {
it('init value', () => {
expect(setState).toHaveBeenCalledWith(0);
});
});
This code doesn't pass.
please help me how to check init state!!
My recommendation for testing the initial state would just be test that React.useState is called with your initial state value.
Is there a way to read the state value after you call the
setState
mock?How to get actual value being set with setState in test case...in this case value of 'count' ...let me put this way...when 'Count Up' test case being run, it updates state of count by 1, if I update wrapper, should I get
1
...and how can we testIf state is changing on onClick function..than how can we test that?
const [disabled, setDisabled] = useState(true)
const addDomain = () => {
console.log("In function")
setDomains([...domains, domain.trim()])
setDisabled(false)
}
how do we modify the intial state value of a component in jest ?