Last active
December 7, 2023 14:46
-
-
Save mauricedb/eb2bae5592e3ddc64fa965cde4afe7bc to your computer and use it in GitHub Desktop.
Testing stateful React hooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from 'react'; | |
export function useCounter(initial = 0) { | |
const [count, setCount] = useState(initial); | |
return [count, () => setCount(count + 1)]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCounter } from './Calculator'; | |
const mockSetState = jest.fn(); | |
jest.mock('react', () => ({ | |
useState: initial => [initial, mockSetState] | |
})); | |
test('Can increment from 1 to 2', () => { | |
const [_, increment] = useCounter(1); | |
increment(); | |
expect(mockSetState).toHaveBeenCalledWith(2); | |
}); |
@muhsalaa, suppose you have a component like this:
const Component = () => {
const setState1 = useState(1);
const setState2 = useState(2);
...
};
In the test, you'll want to do:
import * as React from 'react';
...
it('Should work', () => {
const useStateSpy = jest.spyOn(React, 'useState')
...
expect(useStateSpy).toHaveBeenNthCalledWith(2, 2); // if testing the second `useState`
});
not working ...
How about
setState(prevState => ({ ...prevState, }))
?
How about
setState(prevState => ({ ...prevState, }))
?
Yeah What about class component How do I Change class setState ?
how mock many state in useState?
not working
jest.spyOn(React, 'useState')
.mockImplementationOnce(() => [false, () => null])
.mockImplementationOnce(() => [true, () => null])
You may consider using renderHook (testing-library/react). I find it easy to use.
Here is the sample code:
const { result } = renderHook(() => {
const [isOpen, setIsOpen] = useState(true)
return { isOpen, setIsOpen }
})
const renderValue = await act(() => {
return render(
<ProductFormDialog
isOpen={result.current.isOpen}
setIsOpen={result.current.setIsOpen}
/>
)
})
const displayValue = renderValue.getByTestId('header-container').textContent
expect(displayValue).toEqual('Header')
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to spy specific
useState
hook, when I have more than oneuseState
hook inside my component?