testing-library/react-hooks-testing-library

Cannot test async useCallback in custom hook

mljlynch opened this issue · 4 comments

What is your question:

Consider I have a custom hook that contains a few callbacks

const useDummyHook= ()=>{
  const useAysncCallback = useCallback(async(foo:string) =>{
    if(foo !== "bar){
      throw new Error("foo did not equal bar);
    }
  })
}

I want to test this error throws using renderHook. I cannot get the following to pass:

it('should throw an error if foo does not equal bar', async ()=>{
   const { result } = renderHook(()=>useDummyHook())
   await expect(async() =>{
     result.current.useAysncCallback("notBar")
  }).toThrow()
})

When I run the test, the test says the given function has not thrown an error, but If i do not assert that an error is thrown the test throws an error.

Am I using the custom hooks wrong? Am I missing something in renderHook?

Try adding an await inside the expect callback:

it('should throw an error if foo does not equal bar', async ()=>{
   const { result } = renderHook(()=>useDummyHook())
   await expect(async() =>{
     await result.current.useAysncCallback("notBar")
  }).toThrow()
})

Running:

it('should throw an error if foo does not equal bar', async ()=>{
   const { result } = renderHook(()=>useDummyHook())
   await expect(async() =>{
     await result.current.useAysncCallback("notBar")
  }).toThrow()
})

Jest fails since it did not throw

if I run the following:

it('should throw an error if foo does not equal bar', async ()=>{
   const { result } = renderHook(()=>useDummyHook())
   await result.current.useAysncCallback("notBar")
})

jest fails, but does not say an error was thrown:

    foo did not equal bar

      }
       if (foo !== "bar") {
      throw new Error("foo did not equal bar"); 
               ^
       }

      at call 
      at tryCatch (node_modules/regenerator-runtime/runtime.js:63:40)

This also doesn't work

await expect(async () => {
     const asyncFunc = async () => Promise.reject(new Error('Foo'));
     await asyncFunc();
   }).toThrow();
   ```