What must I do to get this Jest test with Mock Service Worker for React hook to work?

1.5k Views Asked by At

I want to use Jest and Mock Service Worker to test a React Hook with a fetch call The test look like this:

import React from 'react'
import App from './App' 
import {render,screen} from '@testing-library/react'
import { rest } from 'msw'
import { setupServer } from 'msw/node'



it('should display hello world',  () => {
    
     const url = process.env.REACT_APP_BACKEND_URL  +"/helloworld" 
     console.log(url)

     const server = setupServer(
                                 rest.get(url,  (req, res, ctx) =>  {
                                                                       
                                                                       return res(
                                                                                     ctx.status(200),
                                                                                     ctx.json({message:"Hello World"})   
                                                                                  )         
                                                                     }
                          )
                    )

     server.listen()
     console.log("server listen")
     render(<App />);
     const linkElement =  screen.findByText('Hello World')
     expect(linkElement).toBeInTheDocument()

     server.close()
 })

The code that I test look like this

import React from 'react'
import { useState, useEffect } from "react";

function App () {
    
    const [message, setMessage] = useState('')
    
    useEffect(() => {
            const   getMessage = async () => {
                const url = process.env.REACT_APP_BACKEND_URL  +"/helloworld" 
                console.log(url)
               
                      const response = await fetch(url)
                      console.log(response.status)
                      const text = await response.json()
                      console.log(text.message)
                      
                      setMessage(text.message)

                    
            }
            getMessage()
            .catch(console.error)
     }, [])

    return ( <div>{message}</div>)
 }

export default  App ;

When I execute this tests the test results looks like this:

console.log http://localhost:5000/helloworld

  at Object.<anonymous> (src/App.test.jsx:12:14)

console.log server listen

  at Object.<anonymous> (src/App.test.jsx:26:14)

console.log http://localhost:5000/helloworld

  at getMessage (src/App.jsx:11:25)

FAIL src/App.test.jsx ✕ should display hello world (154 ms)

● should display hello world

expect(received).toBeInTheDocument()

received value must be an HTMLElement or an SVGElement.
Received has type:  object
Received has value: {}

  27 |      render(<App />);
  28 |      const linkElement =  screen.findByText('Hello World')
> 29 |      expect(linkElement).toBeInTheDocument()
     |                          ^
  30 |
  31 |      server.close()
  32 |  })

  at __EXTERNAL_MATCHER_TRAP__ (node_modules/expect/build/index.js:386:30)
  at Object.toBeInTheDocument (node_modules/expect/build/index.js:387:15)
  at Object.<anonymous> (src/App.test.jsx:29:26)

----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|------------------- Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 3.061 s Ran all test suites.

Watch Usage: Press w to show more.

What must I do to execute this test sucessfully?

1

There are 1 best solutions below

0
On

Add async on the test: async () => { and await before screen.findByText : await screen.findByText('Hello World') and the bug is fixed

i

mport React from 'react'
import App from './App' 
import {render,screen} from '@testing-library/react'
import { rest } from 'msw'
import { setupServer } from 'msw/node'



it('should display hello world',  async () => {
    
     const url = process.env.REACT_APP_BACKEND_URL + "/helloworld"  // eslint-disable-line
     console.log(url)

     const server = setupServer(
                                 rest.get(url,  (req, res, ctx) =>  {
                                                                       
                                                                       return res(
                                                                                     ctx.status(200),
                                                                                     ctx.json({message:"Hello World"})   
                                                                                  )         
                                                                     }
                          )
                    )

     server.listen()
     console.log("server listen")
     render(<App />);
     const linkElement = await screen.findByText('Hello World')
     expect(linkElement).toBeInTheDocument()

     server.close()
 })