useQuery: Cannot spy the useQuery property because it is not a function
Have a simple useQuery like this
const {
isLoading, isError, data,
} = useQuery(['courses', { userId: someUserId }], fetchDataFromBackendServer);
in my unit test, i want the useQuery return info from very beginning (there's a reason i want to do that, but that's off the topic)
describe.only('Title', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(React, 'useQuery').mockResolvedValue({ isError: false, isLoading: false });
}
...
}
It gives me: Cannot spy the useQuery property because it is not a function; undefined given instead
Hot to fix this please ?
Solution 1:
First of all, React does not provide useQuery
hook.
I suppose you are using react-query
The second, if you want to use jest.spyOn(obj, 'method')
, you can't destruct the method from the obj. That means you should use it like ReactQuery.useQuery()
in your component.
E.g.
import { render } from '@testing-library/react';
import React from 'react';
import * as ReactQuery from 'react-query';
describe('70660790', () => {
test('should pass', () => {
jest.spyOn(ReactQuery, 'useQuery').mockImplementation();
function Test() {
ReactQuery.useQuery('todos');
return null;
}
render(<Test />);
expect(ReactQuery.useQuery).toBeCalledWith('todos');
});
});
Test result:
PASS examples/70660790/index.test.tsx (11.646 s)
70660790
✓ should pass (18 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 13.036 s
See how react-query
exports hooks in barrel file, we have to use namespace import.
The last, you should not mock useQuery
hook the third-party package provides, and test the implementation detail. You should keep using the original useQuery
hook and mock side effect function such as fetchDataFromBackendServer
(I suppose it's an API call to the remote server). Then you can test what's the output of the component.
See testing
Again, don't recommend mock useQuery
. Mock Implementation is probably inconsistent with the original implementation, This will lead your test to build on the wrong mock Implementation. This causes your test case to pass, but the program is not correct at runtime.
And,test implementation details can also make test cases vulnerable. A small change in implementation details will cause the test case to fail and you will have to modify the test case.