I'm trying to test a custom hook that uses useState and useEffect together with a setTimeout that simulates a delay loading some data. Simplified
const useCustomHook = (id: number) => {
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(false);
const [value, setValue] = React.useState<string>();
React.useEffect(() => {
const dummy = ["foo", "bar", "baz"];
// simulate remote call with delay
setTimeout(() => {
id < 3 ? setValue(dummy[id]) : setError(true);
setLoading(false);
}, 1500);
}, [id]);
return [loading, error, value];
};
const App = () => {
const [loading, error, value] = useCustomHook(1);
if (loading) { return <div>Loading...</div>; }
if (error) { return <div>Error</div>; }
return <h1>{value}</h1>;
};
https://codesandbox.io/s/react-typescript-z1z2b
How would you test all possible states (loading, error and value) of this hook with Jest and Enzyme?
Thanks in advance!!!
I guess what you really want is to send an API request inside the useEffect hooks. (sorry if I misunderstand your purpose)
If so, I will check
The test should look like this.
describe('App', () => {
beforeEach(() => {
fetch.resetMocks();
});
it('should fetch the request', async () => {
await act(async () => {
await mount(<App />)
})
expect(fetch).toBeCalledWith('https://dog.ceo/api/breeds/image/random');
});
it('should show loading at first', () => {
// mock useEffect to test the status before the API request
jest
.spyOn(React, 'useEffect')
.mockImplementationOnce(() => {});
const comp = mount(<App />)
expect(comp.text()).toBe('Loading...');
});
it('should display error if api request fail', async () => {
fetch.mockRejectOnce();
let comp;
await act(async () => {
comp = await mount(<App />);
})
comp.update();
expect(comp.text()).toBe('Error');
});
it('should display result if api request success', async () => {
fetch.mockResponseOnce(JSON.stringify({
message: "https://images.dog.ceo/breeds/mastiff-tibetan/n02108551_1287.jpg",
status: "success"
}));
let comp;
await act(async () => {
comp = await mount(<App />);
})
comp.update();
expect(comp.find('img')).toHaveLength(1);
expect(comp.find('img').prop('src'))
.toBe('https://images.dog.ceo/breeds/mastiff-tibetan/n02108551_1287.jpg');
});
});
here is the repo for reference: https://github.com/oahehc/stackoverflow-answers/tree/60514934/src
Furthermore, you pass an id into useCustomHook, I guess this will be used as a parameter in API request. So you might want to add more test cases to check that part.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With