Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Typescript tests - Target container is not a DOM element

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.

  • Good news: error "Target container is not a DOM element" is gone!
  • Bad news: I get a new error (which can be an independent problem, so extracted to a separate question)
like image 359
naXa Avatar asked Jun 09 '20 11:06

naXa


Video Answer


1 Answers

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.

like image 159
takethefake Avatar answered Oct 06 '22 16:10

takethefake