Проверьте файл index.js для создания-реакции-приложения

Я хотел бы иметь 100% охват моего проекта.

img

Для этого мне нужно проверить файл index.js, который является очень простым:

index.js

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

ReactDOM.render(<App/>, document.getElementById('root'));

Я не могу найти, как проверить это. При создании функции, например:

index.js

const index = (div) => {
  ReactDOM.render(<App />, div || document.getElementById('root'));
};

а затем проверить его:

index.test.js

it('renders without crashing', () => {
  const div = document.createElement('div');
  index(div);
});

Я получаю сообщение об ошибке при импорте index: Инвариантное нарушение: _registerComponent (...): Контейнер цели не является элементом DOM.

PS:

Обратите внимание, что у меня уже есть следующий тест, отлично работающий:

App.test.jsx

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App/>, div);
});

Ответ 1

Главный вопрос: что вы хотите там проверить? Если вы хотите проверить, ваш код работает правильно, напишите unit тест, который шпионит за ReactDOM.render и проверяет document.getElementById('root'). Потому что это все, что делает ваш код, вызывая ReactDOM.render с нашим компонентом приложения и конкретным div.

import ReactDOM from 'react-dom';
...
jest.mock('react-dom', ()=> ({render: jest.fn()}))


it('renders without crashing', () => {

  const div = document.createElement('div');
  ReactDOM.render(<App/>, div);
  global.document.getElementById = (id) => id ==='root' && div
  expect(ReactDOM.render).toHaveBeenCalledWith(...)
});

Если вы хотите проверить, действительно ли приложение запускается на вашей странице, вы должны написать интеграционный тест с Selenium или Nightwatch.js

Чтобы получить 100% охват, вы также можете игнорировать этот файл, добавив его в coveragePathIgnorePatterns в настройках шутки.

Ответ 2

Если ваша цель - 100% покрытие вашего проекта, а код в вашем файле index.js тривиален, то это может быть хорошим вариантом для исключения файла из отчета о покрытии, как указывает Андреас Кёберле в своем ответе.

В настоящее время приложение Create-реакции-приложение поддерживает только эти четыре ключа в конфигурации Jest (источник):

collectCoverageFrom
coverageReporters
coverageThreshold
snapshotSerializers

Вот почему

coveragePathIgnorePatterns": ["src/index.js"]

не сработает.

Добавьте следующий код в самую внешнюю область вашего файла package.json:

"jest": {
  "collectCoverageFrom": [
    "src/**/*.{js,jsx}",
    "!src/index.js"
  ]
}

На изображении ниже вы видите результаты тестового прогона с этим кодом, добавленным в package.json исходного приложения, созданного с помощью create-реагировать-приложение v1.4.3. Обратите внимание, что файл index.js больше не отображается в отчете, а также не влияет на процент покрытия.

Coverage report

Ответ 3

Я нашел статью в Интернете, которая объясняет этот способ написания теста...

// index.test.js
import Index from './index.js';

it('renders without crashing', () => {
  expect(JSON.stringify(
    Object.assign({}, Index, { _reactInternalInstance: 'censored' })
  )).toMatchSnapshot();
});

Теперь измените файл index.js соответствующим образом:

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

export default ReactDOM.render(
  <App />,
  document.getElementById('root') || document.createElement('div')
);

Ответ 4

Вот как я тестировал index.js

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));

index.test.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

jest.mock("react-dom", () => ({ render: jest.fn() }));

describe("Application root", () => {
  it("should render without crashing", () => {
    const div = document.createElement("div");
    div.id = "root";
    document.body.appendChild(div);
    require("./index.js");
    expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
  });
});