0

I can't seem to get this simple test to work in react-testing-library & react-native-testing-library. I've tried various combinations of wrapping the render function in act, or using waitFor and other async utils, but the test never waits for the component to re-render after useEffect causes the async api call to set the new state.

Also worth noting I receive the warning: An update to TestComponent inside a test was not wrapped in act(...).`. I'm aware of this issue but no method that I've seen solved it for me.

import React, { useEffect, useState } from 'react'
import { View, Text } from 'react-native'
import { render, waitFor } from 'test-utils'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import { useApi } from './index'

const server = setupServer(
  rest.get('http://localhost/MOCK_VAR/some-endpoint', (req, res, ctx) => {
    return res(ctx.json({ greeting: 'hello there' }))
  })
)

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

function TestComponent() {
  const { apiRequest } = useApi()
  const [result, setResult] = useState(null)

  useEffect(() => {
    makeApiCall()
  })

  const makeApiCall = async () => {
    const apiResult = await apiRequest({ url: '/some-endpoint' })
    console.log(apiResult.greeting) // <-- 'hello there'
    setResult(apiResult.greeting)
  }

  return (
    <View>
      <Text>{result}</Text>
    </View>
  )
}

describe('Test useApi hook', () => {
  test('test post request', async () => {
    const { findByText } = render(<TestComponent />)
    const greeting = await findByText('hello there')
    await waitFor(() => { // <-- never waits
      expect(greeting).toBeTruthy()
    })
  })
})
conor909
  • 1,475
  • 14
  • 29
  • Try settimeout as that will surely wait – Prateek Jan 05 '22 at 16:31
  • @Prateek thanks for the reply, that seems a bit flakey, I'm wondering what the official way from the API would be to do this. Also worth noting I receive the warning: `An update to TestComponent inside a test was not wrapped in act(...)`.` – conor909 Jan 05 '22 at 16:38
  • Not sure whether api is mock. – Prateek Jan 05 '22 at 16:52
  • @Prateek yes it is, using the `msw` lib. I've logged out the results of the api call and it works as expected. – conor909 Jan 05 '22 at 16:54

1 Answers1

0

My issue was awaiting the findBy function. From the docs it says findBy* methods have waitFor already built in. So simply removing the await solved the issue.

What worked for me:

  test('test post request', async () => {
    const { findByText } = render(<TestComponent />)
    const greeting = findByText('hello there')
    waitFor(() => expect(greeting).toBeTruthy())
  })
conor909
  • 1,475
  • 14
  • 29