reactjs 在react中测试时无法在msw中获得响应

9wbgstp7  于 2023-03-17  发布在  React
关注(0)|答案(2)|浏览(160)

我试着测试一个react应用程序,它从jsonplaceholder获取数据,获取函数是通过create async thunk在redux thunk中实现的。
我遵循了每一个指南和每一个相关的答案stackoverflow关于这一点,但没有得到工作的答案。
我正在使用msw来获取mock API。

import {fireEvent,screen,render, findByText, waitFor, waitForElementToBeRemoved} from '@testing-library/react'
import { createMemoryHistory } from 'history'
import { BrowserRouter, Router } from 'react-router-dom'
import Dashboard from '../Pages/Dashboard'
import {rest} from 'msw'
import {setupServer} from 'msw/node'
import { Provider } from 'react-redux'
import { configureStore } from '@reduxjs/toolkit'
import { PostsSlice } from '../Redux/reducers'

const postsResponse = rest.get("https://jsonplaceholder.typicode.com/posts",(req,res,ctx)=>{
    console.log('this line never runs')
    return res(
        ctx.json([{id:1,userId:1,title:"hello world",body:"hola hola"}])
    )
})
const handlers = [postsResponse]
const server = new setupServer(...handlers)
beforeAll(()=>server.listen())
afterEach(()=>server.resetHandlers())
afterAll(()=>server.close())

// Redux specific-->
let store = configureStore({
    initialState:[],
    reducer : PostsSlice.reducer,
})
const MockedComponent = ({children})=>{
    return (
        <Provider store={store}>
            <BrowserRouter>
            {children}
            </BrowserRouter>
        </Provider>
    )
}

describe("Dashboard Page Test",()=>{
    test("should render hello world ",async()=>{
        render(<MockedComponent><Dashboard /></MockedComponent>);
        const element =  await findByText("hello world")
        expect(element).toBeInTheDocument();
    })

})

我收到以下错误

● Dashboard Page Test › should render hello world 

    TypeError: Cannot read property 'map' of undefined

      42 |       
      43 | <Grid sx={{padding:2}}  container spacing={4}>
    > 44 |     {posts.map(item=>(
         |            ^
      45 |   <Grid item xs={12} md={8} lg={4} xl={2} key={item.id}  >
      46 |     <div className='postitems' onClick={()=>handleNavigation(item.id)} >
      47 |       <PostItem title={item.title}  />

我尝试了msw与2 react应用程序,一个是这个和其他是相当简单的没有redux。它失败了两个。
尝试了whatwg-fetch,但没有成功。尝试了wait with fetch,但没有成功尝试了waitForElementToBeRemoved,也没有成功。
先谢了。
编辑: Jmeter 板组件的代码

import { CircularProgress, Grid } from '@mui/material'
import React,{useEffect} from 'react'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import PostItem from '../Components/PostItem'
import { PostsType } from '../Helper/interfaces'
import { useAppDispatch, useAppSelector } from '../Hooks/reduxhooks'
import useGetError from '../Hooks/useGetError'
import useGetPosts from '../Hooks/useGetPosts'
import useGetStatus from '../Hooks/useGetStatus'
import { FetchPosts } from '../Redux/reducers'

const Dashboard: React.FC = () => {
  let dispatch = useAppDispatch()
  let navigate = useNavigate()
  let posts = useGetPosts()
  const status = useGetStatus()
  const error = useGetError()

  const handleNavigation:(id:number)=>void = (id)=>{
      navigate(`/posts/${id}`)
  }
  useEffect(()=>{
    if (status === 'idle'){
      dispatch(FetchPosts())
    }
    
  },[])

  if(status === 'loading'){
    return <CircularProgress color='success' />
  }

  if (status === 'failed'){
    return <div>{error}</div>
  }

  return (
    <div>
      <h1>Dashboard</h1>
      
<Grid sx={{padding:2}}  container spacing={4}>
    {posts.map(item=>(
  <Grid item xs={12} md={8} lg={4} xl={2} key={item.id}  >
    <div className='postitems' onClick={()=>handleNavigation(item.id)} >
      <PostItem title={item.title}  />
    </div>
  </Grid>
    ))}
</Grid>
    </div>
  )
}

export default Dashboard
3z6pesqy

3z6pesqy1#

经过几天的试验,我发现了错误。如果其他人没有得到MSW的回应,这可以帮助你。
msw没有返回任何响应,因为我正在重写存储。
你需要做的是使用rtlRenderer和自定义提供程序(访问redux测试部分了解更多细节)
并且在测试用例中不要提供任何提供者,很可能你会使用react-router-dom,所以要确保你提供给组件,这样一切都会完美地工作。
同样对于JSON占位符API,我必须使用完整的URL,即“https://jsonplaceholder.typicode.com/posts“,但在文档中建议只使用“/posts”。

s3fp2yjn

s3fp2yjn2#

store.ts配置必须更改如下,并且公共目录应包含mockServiceWorker.js

import { combineReducers, configureStore } from '@reduxjs/toolkit'
import { setupListeners } from '@reduxjs/toolkit/query'

import counterReducer from './features/counter/counterSlice'
import { docsApi } from './services/docs'

const rootReducer = combineReducers({
  counter: counterReducer,
  [docsApi.reducerPath]: docsApi.reducer,
})

export const store = configureStore({
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(docsApi.middleware),
  reducer: rootReducer,
  preloadedState: {}
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

setupListeners(store.dispatch)

相关问题