This micro blog entry is for those who:
- use
renderHook
from@testing-library/react-hooks
to test their own custom hooks - want to assert that the custom hook did not throw
So, by instinct, one probably would do sth along this line:
// HEADS UP: WRONG APPROACH, DO NOT APPLY TO YOUR WORK
import { renderHook } from '@testing-library/react-hooks'
import { myCustomHook } from './my-custom-hook'
it('should work', () => {
// no, sadly this doesn't work, mate
expect(() => renderHook(() => myCustomHook())).not.toThrow()
})
The reason why the above approach doesn’t work is quite obvious, if you think about it. You were expecting the renderHook
function to not throw, and _not_ your actual custom hook. The test target has been wrong from the 1st place.
But then what should we do? In expect(<something>).not.toThrow()
, the <something> has to be a function, so if we don’t pass the function that calls renderHook
in there, how else do we invoke the custom hook?
The answer lies in the result of renderHook
. Turns out if we use this library function, we’re well covered.. more than we expected 😉 The code speaks for itself:
// now this is a working approach
// you're safe to copy & paste 😉
it('should work', () => {
const { result } = renderHook(() => myCustomHook())
expect(result.error).toBeUndefined()
})
As you see there, renderHook
returns to us quite a few interesting objects, one of which is named result
. Inspecting result.error
allows us to check if there was any error thrown during the invocation of our custom hook. Simple as that.
This goes without saying, if we wish to do the other way around e.g. assert that our custom hook _did_ throw an error, then we could do something along this line:
expect(result.error.message).toBe('noooooooo!')
Anyway, you know your error best 😉 So, turn the above to whatever form that works best for your use case.
Bonus: as hinted above, besides result
, renderHook
gives us a number of other very useful controls. Discussing them is beyond the scope of this blog entry, and I’ll leave them as a bonus “take-home material” 🙂
Cheers,