0

I am testing a custom hook called useRequest that's responsible for sending a particular request. It looks like this:

export const useRequest = () => {
  const {
    updateContextState
  } = useSomeContext()
  const {
    isLoading,
    mutate,
    isSuccess
  } = useMutation(someRequest, {
    onSuccess: (res) => {
      updateContextState(res)
    }
  })

  const sendRequest = () => {
    ...aditional code...
    mutate()
  }

  return {
    sendRequest,
    isLoading,
    isSuccess
  }
}

App.ts:

export const App = () => < SomeProvider > ... < /SomeProvider>

useRequest.test.tsx:

/* eslint-disable import/order */
import {
  AllTheProviders,
  renderHook,
  act,
  MockReactQueryProvider,
  waitFor
} from 'test-utils/test-utils'
import {
  SomeContext
} from 'context/SomeContext'
import {
  rest
} from 'msw'
import {
  setupServer
} from 'msw/node'
import useRequest from './useContinueRequest'
import {
  ReactNode
} from 'react'
import {
  BrowserRouter
} from 'react-router-dom'
import {
  QueryClient,
  QueryClientProvider
} from 'react-query'

const server = setupServer(
  rest.post(
    'http://localhost:3000/api/getData',
    (_req, res, ctx) => {
      return res(ctx.delay(500), ctx.status(200), ctx.json({
        greeting: 'hello there'
      }))
    }
  )
)

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retryDelay: 1,
      retry: 0
    }
  }
})

const updateContextStateMock = jest.fn()
const mockContextValues = {
  updateContextState: updateContextStateMock,
}
const wrapper = ({
  children
}: {
  children: ReactNode
}) => ( <
  QueryClientProvider client = {
    queryClient
  } >
  <
  BrowserRouter >
  <
  SomeContext.Provider value = {
    mockContextValues
  } > {
    children
  } <
  /SomeContext.Provider> <
  /BrowserRouter> <
  /QueryClientProvider>
)

beforeAll(() => server.listen())
afterEach(() => {
  server.resetHandlers()
  queryClient.clear()
})
afterAll(() => server.close())

describe('useRequest', () => {
  test('sendContinueRequest is being called', async() => {
    const {
      result
    } = renderHook(() => useRequest(), {
      wrapper
    })

    await act(async() => {
      await result.current.sendRequest()
    })

    await waitFor(
      async() => {
        await expect(result.current.isSuccess).toBeTruthy()
      }, {
        timeout: 1000
      }
    )

    expect(updateContextState).toHaveBeenCalled()
  })
})

As you can see I'm awaiting for request to be successfull, which I've assured actually happenes through debugging. But for some reason updateContextState function is never being fired? Thanks for any help

I've tried the code I've simplified above, however I couldn't get updateContextState to be fired

EDIT: If I put updateContextState inside sendRequest function like so the test passes:

  const sendRequest = () => {
    ...aditional code...
    updateContextState() <- 
    mutate()
  }

So I guess it has something to do with async code not being resolved

ljkove
  • 1
  • 2

0 Answers0