I'm trying to test a hook in isolation with @testing-library/render-hooks
in a React Native project. The hook I have looks something like this:
const useStatus = () => {
const [ status, setStatus ] = useState(null)
const { data: data1 } = useDataHook1()
const { data: data2 } = useDataHook2()
useEffect(() => {
if (data1 && data2) {
// Some logic to determine status based on data1 + data2
setStatus(...)
}
}, [data1, data2])
return { status }
}
So I want to test useStatus
and I'd like to mock useData1
and useData2
, all three hooks of which are defined in the same file. My test looks like so:
import * as hooks from 'path/to/hooks'
const data1Spy = jest.spyOn(hooks, 'useData1')
const data2Spy = jest.spyOn(hooks, 'useData2')
describe('useStatus', () => {
it('should render', async () => {
data1Spy.mockReturnValue({ data: 'foo' }
data2Spy.mockReturnValue({ data: 'bar' }
const { result, waitForNextUpdate } = renderHook(() => hooks.useStatus())
await waitForNextUpdate()
console.log(result.current.status)
}
}
The console logs values that I would expect if the nested data hooks weren't returning, and the error:
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
appears, which tells me that the mocks aren't being set correctly. (Thinking the SWR queries are trying to dispatch in a test environment, leading to unresolved promises floating around after the test finishes.) Some things I've tried:
- Using
mockReturnValue
as seen in the above code - Using
mockImplementation
instead ofmockReturnValue
- Using
jest.mock
+jest.requireActual
pattern as is done here
I'm not sure what else to try. I've been able to mock hooks before using the above pattern when rendering a component, but this is my first time working with rendering the hook directly. Any thoughts?