Ошибка неизменяемого типа при использовании Jest mount

Итак, у меня есть класс React, назовем его A. Я провожу тест на шутку, но продолжаю получать

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

В классе React я делаю: export class A extends Component ..

В тестовом файле jest, который я делаю: import { A } from './A.js'

когда я бегу: const wrapper = mount(<A />)

Я получаю сообщение об ошибке выше. Я для шутки использую среду jsdom. Я не понимаю, почему это не сработает. Я читал, что некоторые люди экспортируют по умолчанию, но я не понимаю, почему импорт собственного имени не должен работать. Есть ли у кого-нибудь идеи, в чем может быть проблема?

реальный код: файл jest:

import Adapter from 'enzyme-adapter-react-16';
import Enzyme, { shallow, mount } from 'enzyme';
import React from 'react';

import { A } from '../A';

Enzyme.configure({ adapter: new Adapter() });

/**
 * Test Suite
 */
describe('A test', () => {
 it('calls componentDidMount', () => {
   const wrapper = mount(<A />);
 })
})

класс реакции:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export class A extends Component {
...
}

Конфигурация шутки:

module.exports = {
    clearMocks: true,

    // The directory where Jest should output its coverage files
    coverageDirectory: 'coverage',

    // The test environment that will be used for testing
    testEnvironment: 'jsdom',
    testURL: 'http://localhost/',

    // Directory to search for tests
    roots: ['src/'],

    // The glob patterns Jest uses to detect test files
    testMatch: [
        '**/__tests__/**/*.[jt]s?(x)',
        '**/?(*.)+(spec|test).[tj]s?(x)'
    ],

    // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
    testPathIgnorePatterns: [
        '/node_modules/'
    ],

    snapshotSerializers: [
        'enzyme-to-json/serializer'
    ]
};


person Abdullah Monoar    schedule 03.04.2019    source источник
comment
Вы можете поделиться реальным кодом? Ваш теоретический пример должен работать, но я подозреваю, что в вашем коде может быть проблема. Поделитесь минимальным воспроизводимым примером   -  person LMulvey    schedule 03.04.2019
comment
@LMulvey Я обновил реальным кодом   -  person Abdullah Monoar    schedule 03.04.2019


Ответы (2)


Это ошибка, которую вы получаете, когда пытаетесь отобразить Object как Component.

Вот пример:

A.js

import * as React from 'react';

const AnObject = {};  // <= NOT a component

export class A extends React.Component {
  render() {
    return (<AnObject/>);  // <= Attempt to render an object as a component
  }
}

A.test.js

import * as React from 'react';
import { mount } from 'enzyme';

import { A } from './A';

test('A', () => {
  const wrapper = mount(<A/>);  // <= Fails with "Invariant Violation: Element type...
});

... что дает следующую ошибку:

Инвариантное нарушение: недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: объект. Скорее всего, вы забыли экспортировать свой компонент из файла, в котором он определен, или вы могли перепутать импорт по умолчанию и именованный импорт.

Проверьте метод рендеринга A.

  5 | 
  6 | test('A', () => {
> 7 |   const wrapper = mount(<A/>);
    |                   ^
  8 | });
  9 | 

Вы захотите проверить A в момент теста и убедиться, что это действительно ваш компонент.

Затем работайте в обратном направлении и убедитесь, что все, что отрисовывается как компонент A, на самом деле является компонентом (и так далее), пока вы не найдете не-компонент, который используется в качестве компонента.

person Brian Adams    schedule 04.04.2019

LayoutGroup не является экспортом по умолчанию

Вы не можете вызвать LayoutGroup через import { A } from '../A';, он не экспортируется по умолчанию, поэтому вы не можете переименовать его как именованный импорт.

Сделать что-то вроде этого изменения

import { A } from './A.js'

to

import A from './A.js'

и

export class LayoutGroup extends Component {

to

export default class LayoutGroup extends Component {

person Joe Lloyd    schedule 03.04.2019
comment
мои извинения, это была опечатка с моей стороны. Я заменил все экземпляры LayoutGroup на A. Пропустил этот. - person Abdullah Monoar; 03.04.2019