Reputation: 1117
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?
Upvotes: 2
Views: 1598
Reputation: 1117
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()
})
Upvotes: 0