7

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)
14
  • looks like you are declaring Feature.... Commented Jun 11, 2020 at 12:51
  • it looks like something is trying to render your index.tsx.... Commented Jun 11, 2020 at 12:52
  • @DanielA.White sorry, changed Feature to feature in question. Commented Jun 11, 2020 at 12:55
  • What is it you're currently looking for to test? In general, you would not test the index.ts which renders your application to the dom. you would either test everything inside your React.render method since this is what will happen within your test as well. The react components in your tests will be rendered to a virtual dom. Commented Jun 11, 2020 at 13:03
  • @DanielA.White added details to the bottom of the question. Commented Jun 11, 2020 at 13:07

1 Answer 1

3
+100

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.