I'm trying to add Jest support for testing code in my webpack based application. I think I have the basic configuration right, as a non-component based test (like 'adds numbers' below) passes. However, when I try to interact with the DOM, an error results. I'm trying a variation of the smoketest scenario described in the create-react-apps docs docs (Test components section). My test file look like this:
import React from 'react';
import ReactDOM from 'react-dom';
it('adds number', () => {
expect(2 + 2).toBe(4);
});
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<div/>, div);
});
and the output is:
v adds number (10ms)
× renders without crashing (3ms)
renders without crashing
TypeError: Cannot read property 'render' of undefined
44 | it('renders without crashing', () => { 45 | const div = document.createElement('div'); 46 | ReactDOM.render(<div/>, div); | ^ 47 | });
at Object.<anonymous> (/pathto/TestFile.test.tsx:46:12)
My application is not built with create-react-app. Instead I tried to follow the instructions in Jest webpack documentation, modifying it in support of Typescript. Should I expect the sample 'renders without crashing' to work in my application? Do I need to set any browser Jest configuration to support this? This is the main configuration in my package.json related to Jest:
"jest": {
"roots": [
"src/app/react"
],
"moduleNameMapper": {
"\\.(css)$": "identity-obj-proxy"
},
"transform": {
"^.+\\.tsx?$": "ts-jest",
"^.+\\.(js|jsx)$": "babel-jest",
".+\\.(scss)$": "./node_modules/jest-css-modules-transform"
},
"moduleFileExtensions": [
"js",
"ts",
"tsx"
]
},
Add this to your tsconfig.json
:
{
"compilerOptions": {
...
"esModuleInterop": true
},
...
}
Details
The issue stems from how this line is transpiled:
import ReactDOM from 'react-dom';
That line means import the default
export from the react-dom
module as ReactDOM
.
react-dom
ships as a CommonJS module so technically it doesn't have a default
export.
Setting the esModuleInterop
flag to true
lets you import its single exported value as if it was the default
export of a TypeScript or ES6 module.
If you don't want to add esModuleInterop
config for some reason, the correct syntax to import a module in TypeScript as a single name is:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
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