Can anyone help with my tests for a React App with Redux store. I based my project on the counter Redux example app which cam with the below App.test.js file.
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
test('renders learn react link', () => {
const { getByText } = render(
<Provider store={store}>
<App />
</Provider>
);
expect(getByText(/learn/i)).toBeInTheDocument();
});
When I run the test it gives the error:
TypeError: Cannot destructure property ‘basename’ of
‘React__namespace.useContext(…)’ as it is null.
I think this is because my app is getting data from Reddit API so nothing in store until this data is returned.
The above App.test.js test works on the Redux example project which I think is because the store in that example has fixed values to begin with.
App.js
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import './App.css';
import Header from './features/Header/Header';
import { Posts } from './features/Posts/Posts';
import { SubReddit } from './features/Subreddit/SubReddit';
import { Comments } from './features/Comments/Comments';
import Footer from './features/Footer/Footer';
function App() {
return (
<div>
<Header />
<div className='homePage'>
<SubReddit />
<Routes>
<Route path="/" element={<Posts />} />
<Route path="/Comments" element={<Comments />} />
</Routes>
</div>
<Footer />
</div>
);
}
export default App;
store.js
import { configureStore } from '@reduxjs/toolkit';
import postsReducer from '../features/Posts/postsSlice';
import subRedditReducer from
'../features/Subreddit/subRedditSlice';
import commentsReducer from '../features/Comments/commentsSlice';
export const store = configureStore({
reducer: {
posts: postsReducer,
subReddits: subRedditReducer,
comments: commentsReducer
},
});
2
Answers
It looks like it’s related to the usage of
react-router-dom
.If you wanna use
<Routes>
, your<App>
should be wrapped in a Router, like<BrowserRouter/
>, like so :See : https://stackoverflow.com/a/75728680/1489088
Also : https://reactrouter.com/en/main/router-components/browser-router
It appears that
App
is rendering some components that require a routing context that is provided by one of thereact-router-dom
router components.App
works in your regular code because you are likely wrapping it in a router, but in the unit test it is not.Generally in non-DOM environments, like Node.js, where you are running your tests you can’t, or shouldn’t, use the
BrowserRouter
. In unit testing you can use theMemoryRouter
.Example:
If you need to specify being on any specific route then use the
initialEntries
andinitialIndex
props. For example, if you had anApp
test that needed to be on the"/comments"
path use the following:FWIW I don’t see where
App
is rendering a link with the text "learn", so I suspect you are testing too much in this specific test. I suspect the "learn" link is rendered in theHeader
and should probably be tested with that component’s unit testing.