Problem
We have a usePaymentEffectReducer
that needs to trigger useQuery
as a hook:
1 | import { useQuery } from '@apollo/client' |
In order to test the upper hook, the GraphQL query done by Apollo client needs to be mocked out.
Finding 1: MockedProvider
https://www.apollographql.com/docs/react/v2/api/react-testing/
Example:
1 | it('runs the mocked query', () => { |
New Problem: I don’t need a component, I need to render a hook
I cannot just do:
1 | const { result, waitForNextUpdate } = renderHook(() => |
Finding 2:
https://react-hooks-testing-library.com/usage/advanced-hooks#context
Often, a hook is going to need a value out of context. The useContext hook is really good for this, but it will often require a Provider to be wrapped around the component using the hook. We can use the wrapper option for renderHook to do just that.
Example:
1 | const wrapper = ({ children }) => ( |
New problem: mocking graphQL
error in mocks gets type error
1. Specify graphQL error as a field of result
https://github.com/apollographql/react-apollo/issues/1127
2. use GraphQLError
constructor from graphql
library
1 | import { GraphQLError } from 'graphql' |
New problem: wrong act
?
Symptoms
I imported act
together with renderHook
, thinking that would make sure my act
will be the correct one:
1 | import { renderHook, act } from '@testing-library/react-hooks' |
The code where I used act
looks like this:
1 | const { result } = renderHook(() => usePaymentEffectReducer(TEST_ARGS), { |
However, I still get an error message like this:
1 | Warning: It looks like you're using the wrong act() around your test interactions. |
Research on act
doc
According render-hooks/act:
This is the same act function function that is exported from your chosen renderer.
Which of the two renderers will I import by importing react-hooks
?
When using standard import for this library (show below), we will attempt to auto-detect which renderer you have installed and use it without needing any specific wiring up to make it happen. If you have both installed in your project, and you use the standard import (see below) the library will default to using react-test-renderer.
We use react-test-renderer by default as it enables hooks to be tested that are designed for either react or react-native and it is compatible with more test runners out-of-the-box as there is no DOM requirement to use it.
The interesting thing is that the wrapper
will use dom
renderer, so if act
use the native
renderer imported by auto detection, there will be a mismatch.
If I import specifically dom
renderer like this:
1 | import { renderHook, act } from '@testing-library/react-hooks/dom' |
The mismatch will be resolved.