I have a custom hook with that returns api calls. It looks like this:
export const useApiData = () => {
const queryClient = useQueryClient();
const [networkError, setNetworkError] = useState<string>(null);
const getCase = (caseId: number) =>
useQuery({
queryKey: `case-${caseId}`,
queryFn: (): Promise<AxiosResponse<CaseDto>> => CASE_API.api.getCase(caseId),
staleTime: Infinity,
suspense: true,
});
const api = {
getCase,
};
return { api, networkError };
};
I would like to stub this custom hook with a sinon stub:
export function mockGetCase(sinonSandbox: SinonSandbox = sinon.createSandbox()) {
const { api } = useApiData();
sinonSandbox.stub(api, "getCase").callsFake(() => {
return () => Promise.resolve(caseMockApiData);
});
return sinonSandbox;
}
But, this won’t work since I am calling hook outside of react component:
Warning: Invalid hook call. Hooks can only be called inside of the
body of a function component. This could happen for one of the
following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug
How can I stub a custom react hook with sinon?
and fix this problem.
I am using this hook like this in my components:
const { caseId } = useCase();
const { api } = useApiData();
const {
data: { data: case },
} = api.getCase(caseId);
The CASE_API looks like this:
export const CASE_API: CaseApi<CaseDto> = useApi(
new CaseApi({ baseURL: environment.url.case }),
"case",
"gcp"
);
And the hook useApi looks like this:
export function useApi<T extends AxiosClient>(api: T, app: string, cluster: string): T {
api.instance.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => {
const secHeaders = await createDefaultHeaders(app, cluster);
Object.assign(config.headers, secHeaders);
return config;
},
function (error) {
// error handling here
return Promise.reject(error);
}
);
api.instance.interceptors.response.use(
function (response) {
return response;
},
function (error) {
return Promise.reject(error);
}
);
return api;
}
const createDefaultHeaders = async (app: string, cluster: string) => {
const idToken = await SecuritySessionUtils.getSecurityTokenForApp(app, cluster);
const correlationId = SecuritySessionUtils.getCorrelationId();
return {
Authorization: "Bearer " + idToken,
"Content-type": "application/json; charset=UTF-8",
"X-Correlation-ID": correlationId,
"Call-Id": correlationId,
"Consumer-Id": SecuritySessionUtils.getAppName(),
};
};