I made a custom hook and I’m trying to write a test for it:
hook
import { useQuery } from '@redwoodjs/web';
import { firebaseClient } from 'src/auth';
const GET_TENANT = gql`
query getTenant($domain: String!) {
tenantByDomain(domain: $domain) {
identityPlatformId
domain
}
}
`;
const useTenant = () => {
const firebaseAuth = firebaseClient?.firebaseAuth;
const auth = firebaseAuth.getAuth();
const subdomain = window.location.host.split('.')[0];
const tenant = useQuery(GET_TENANT, { variables: { domain: subdomain } });
return {
auth,
tenantId: tenant?.data?.tenantByDomain?.identityPlatformId,
};
};
export default useTenant;
test
import { renderHook } from '@testing-library/react-hooks';
import useTenant from './use-tenant';
describe('useTenant', () => {
it('gets tenantId', () => {
const expectedTenantId = 'test-tenant-id';
mockGraphQLQuery('getTenant', (_variables) => {
return { tenantId: expectedTenantId };
});
const { result } = renderHook(() => useTenant());
expect(result.current).toEqual(expectedTenantId);
});
});
I’m getting the error
You must register a useQuery hook via the GraphQLHooksProvider
According to the documentation I found here Testing | RedwoodJS Docs I would have thought all I needed was mockGraphQLQuery
but I guess I’m missing something else. Any ideas?
Hi @LarkSoftware I’ve never tried to do that before, but I wonder if beforeQuery
might work here.
See: https://redwoodjs.com/docs/cells#beforequery
beforeQuery is a lifecycle hook. The best way to think about it is as an API for configuring Apollo Client’s Query component (so you might want to check out Apollo’s docs for it).
By default, beforeQuery gives any props passed from the parent component to Query so that they’re available as variables for QUERY. It’ll also set the fetch policy to ‘cache-and-network’ since we felt it matched the behavior users want most of the time.
So, perhaps:
// The Cell will take no props: <Cell />
export const beforeQuery = () => {
return {
variables: { domain: window.location.host.split('.')[0] }
}
}
Also, are you implementing Firebase auth on your own or using the RedwoodJS Firebase setup?
Hi @LarkSoftware I’ve never tried to do that before, but I wonder if beforeQuery
might work here.
Just to be clear, my custom hook works great. It is the test I’m trying to write for it that I’m having trouble with. For some reason the testing framework doesn’t like my use of useQuery
it want’s me to register it somehow. I thought mockGraphQlQuery
would take care of that for me, but it does not seem to. I do not get this error when I run the hook in the browser, only when I try to create a test for it.
Yes, I got that new error too.
Seems like you can wrap the component in your test with
<GraphQLHooksProvider
useMutation={jest.fn().mockReturnValue([jest.fn(), {}])}
useQuery={jest.fn().mockReturnValue({ data: {} })}
>...</GraphQLHooksProvider>
But not sure if that’s the right way to do?
I was just coming here to post that I have made it past my initial error:
You must register a useQuery hook via the GraphQLHooksProvider
The problem was that I was importing renderHook
from the wrong place.
// wrong
import { renderHook } from '@testing-library/react-hooks';
// right
import { renderHook } from '@redwoodjs/testing/web';
Now things are looking much better except my mockGraphQLQuery
is getting fired after the expect
call. This means the result
has not been populated by the time it gets evaluated. I’m still trying to track this down but I’m done for today. I’ll take another look tomorrow.
Actually I finally got it working. Here is what I came up with:
import { renderHook, waitFor } from '@redwoodjs/testing/web';
jest.mock('../auth');
import useTenant from './use-tenant';
describe('useTenant', () => {
it('gets tenantId', async () => {
const expectedTenantId = 'test-tenant-id';
mockGraphQLQuery('getTenant', (variables) => {
return {
tenantByDomain: {
identityPlatformId: expectedTenantId,
domain: variables?.domain,
},
};
});
const { result } = renderHook(() => useTenant());
await waitFor(() => {
return expect(result?.current?.tenantId).toEqual(expectedTenantId);
});
});
});
Thank you to everyone that offered help.