I am trying to test a react app where it is fetching the data from jsonplaceholder. The fetch function is implemented in redux thunk via create async thunk.
i followed every guide and every related answer on stackoverflow regarding this but got no working answer.
i'm using msw for mock api fetching.
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();
})
})
I'm getting the following error
● 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} />
i tried msw with 2 react app, one is this and other was pretty simple without redux. it failed in both.
tried whatwg-fetch didn't worked. tried await with fetch didn't worked tried waitForElementToBeRemoved also didn't worked.
Thanks in advance.
Edit: the code for dashboard component
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