TypeError: невозможно прочитать свойство «рендеринг» неопределенного в тесте Jest с использованием ReactDOM

Я пытаюсь добавить поддержку Jest для тестирования кода в своем приложении на основе веб-пакета. Я думаю, что у меня правильная базовая конфигурация, поскольку тест, не основанный на компонентах (например, «добавляет числа» ниже), проходит. Однако, когда я пытаюсь взаимодействовать с DOM, возникает ошибка. Я пробую вариант сценария smoketest, описанного в документах Документы по созданию-реагированию-приложений (раздел «Тестовые компоненты»). Мой тестовый файл выглядит так:

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);
});

и вывод:

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)

Мое приложение не создано с помощью приложения create-реагировать. Вместо этого я попытался следовать инструкциям в Документация веб-пакета Jest, изменив его для поддержки Typescript. Должен ли я ожидать, что пример «рендеринга без сбоев» будет работать в моем приложении? Нужно ли мне устанавливать какую-либо конфигурацию браузера Jest для поддержки этого? Это основная конфигурация в моем package.json, связанная с 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"
  ]
},
Поиск всех неиспользуемых файлов в проекте
Поиск всех неиспользуемых файлов в проекте
Количество файлов в проекте растет по мере его развития. И если быть по-настоящему честным, их продвижение происходит в геометрической прогрессии...
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
5
0
3 241
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Добавьте это в свой tsconfig.json:

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  },
  ...
}

Подробности

Проблема связана с тем, как эта строка транспилируется:

import ReactDOM from 'react-dom';

Эта строка означает импорт default экспорта из модуля react-dom как ReactDOM.

react-dom поставляется как модуль CommonJS, поэтому технически у него нет default экспорта.

Установка флага esModuleInterop в true позволяет импортировать одно экспортированное значение, как если бы это был default экспорт модуля TypeScript или ES6.

Большое спасибо! Хорошее объяснение :)

Notre 09.04.2019 17:44

Постучав головой о стол некоторое время, я наконец увидел ваш ответ и исправил его. Действительно ценю это

dante 04.05.2020 18:36

Если вы по какой-то причине не хотите добавлять esModuleInterop config, правильный синтаксис для импорта модуля в TypeScript как одно имя:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

Другие вопросы по теме