I'm new to testing React/Typescript apps.
command (alias for react-scripts test
):
yarn test
output:
FAIL src/containers/pages/Feature/Feature.test.tsx
● Test suite failed to run
Target container is not a DOM element.
17 | const { store, persistor } = configureStore(history, initialState);
18 |
> 19 | ReactDOM.render(
| ^
20 | <Provider store={store}>
21 | <PersistGate loading={null} persistor={persistor}>
22 | <ConnectedRouter history={history}>
at Object.render (node_modules/react-dom/cjs/react-dom.development.js:27596:13)
at Object.render (src/index.tsx:19:10)
simple test code:
import * as React from 'react';
import { create } from 'react-test-renderer';
import Feature from "./Feature";
describe('Feature page component', () => {
test('matches the snapshot', () => {
const feature = create(
<Feature />,
);
expect(feature.toJSON()).toMatchSnapshot();
});
});
src/index.tsx file in fact contains ReactDOM.render()
call that fails in tests, but what's a working alternative?
Note: the app itself works fine, it's just failing to run in test mode.
in src/index.tsx file I have:
export const history = createBrowserHistory({
basename: '/admin',
});
const initialState: StoreState = (undefined as unknown) as StoreState;
const { store, persistor } = configureStore(history, initialState);
and then in services and sagas I import history
and store
from index.tsx. may it be the problem causing tests to fail?
I tried to extract history
and store
to a separate file (as suggested by commenters). Now the above code is inside src/initialState.ts
.
The problem that is happening in your test right now is that you want to test a component that imports something from index.tsx
. When your're importing from index.tsx
ReactDOM.render
is called as well and your tests fail.
Ensure to not import anything from
index.tsx
and move your logic you've defined there in a separate file.
In general, you would have an index file for your Application e.g.:index.tsx
which imports your App.tsx
and just cares about rendering the React component to the dom with ReactDOM.render
.
In the App.tsx
you would define all components like Provider
, PersistGate
, or even Feature
when you're testing your component you want to be sure it doesn't include the ReactDOM.render
, because what you're doing when testing is rendering the Component under test inside a virtual dom and unfortunately this clashes with ReactDOM.render
I've provided an example on how I would set something like this up in a codesandbox
Nowadays I prefer testing components with @testing-library/react instead of react-test-renderer
which has also become the default testing library with create-react-app
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With