我必须做什么才能使用 Mock Service Worker 进行 Jest 测试才能使 React hook 正常工作?

发布于 2025-01-19 12:48:38 字数 3770 浏览 5 评论 0原文

我想使用开玩笑和模拟服务工作者用fetch呼叫测试react钩子 测试看起来像:

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()
 })

我测试的代码看起来像这样的

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 ;

执行此测试时,

测试结果如下: console.log http:// localhost:5000/helloworld

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

console.log 服务器收听

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

控制台 http:// localhost:5000/helloworld

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

失败src/app.test.jsx ✕应该显示Hello World(154 ms)

●应显示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)

---------------------------------------------------------------------- ----- | ------------------------------------------------------- 文件| %stmts | %分支| %funcs | %线|未发现的行# ---------- | ------------ | ------------------------------------------------------------- - | ------------------------------- 所有文件| 0 | 0 | 0 | 0 |
---------- | ------------ | ------------------------------------------------------------- - | ------------------------------- 测试套件:1个失败,总共1个 测试:1个失败,总共1个 快照:总计0 时间:3.061 s 运行所有测试套件。

观看用法:按W显示更多。

我该怎么做才能成功执行此测试?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水晶透心 2025-01-26 12:48:38

在测试中添加异步:async() => { 并在 screen.findByText 之前等待:等待 screen.findByText('Hello World') 并且错误已

修复

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()
 })

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()
 })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文