Я продолжаю получать эту ошибку при тестировании моего компонента TodoList:

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

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

TodoList.js:

import React from 'react';

import Todo from 'Todo';

class TodoList extends React.Component {
    renderTodos(todos) {
        return todos.map(todo => {
            return <Todo key={todo.id} {...todo} />;
        });
    }
    render() {
        const { todos } = this.props;
        return (
            <div>
                {this.renderTodos(todos)}
            </div>
        );
    }
}

export default TodoList;

TodoList.test.js:

const React = require('react');
const ReactDOM = require('react-dom');
const TestUtils = require('react-addons-test-utils');
const expect = require('expect');
const $ = require('jQuery');

const TodoList = require('TodoList');
const Todo = require('Todo');

describe('TodoList', () => {
    it('should exist', () => {
        expect(TodoList).toExist();
    });

    it('should render one Todo component for each todo item', () => {
        const todos = [{
            id: 1,
            text: "Do something"
        }, {
            id: 2,
            text: "Check mail"
        }];
        const todoList = TestUtils.renderIntoDocument(<TodoList todos={todos} />);
        const todoComponents = TestUtils.scryRenderedComponentsWithType(todoList, Todo);

        expect(todoComponents.length).toBe(todos.length);
    });
});

Ссылка на исходный код: ссылка на исходный код

1
Funk Soul Ninja 27 Ноя 2016 в 05:51

3 ответа

Лучший ответ

В своем TodoList.Test.js удалите

const TodoList = require('TodoList');
const Todo = require('Todo');

И заменить его на

import TodoList from 'TodoList'
import Todo from 'Todo

Это потому, что вы экспортируете свои компоненты способом ES6 и импортируете его способом nodejs.

Если вы все еще хотите использовать require в своем тесте, вам придется заменить

export default TodoList

С участием

module.exports = TodoList;

Надеюсь, это поможет :)

2
Swapnil 27 Ноя 2016 в 04:05

По умолчанию в Node, если вы используете этот синтаксис:

require('Todo')

Он будет искать модуль узла Todo, так как он будет искать в вашем каталоге node_modules каталог с именем Todo. Узел не знает, как использовать настраиваемые разрешения Webpack. У вас есть этот параметр:

    modulesDirectories: [
        'node_modules',
        './app/components'
    ],

Это означает, что каждый раз, когда Webpack видит require('Todo') или import from 'Todo', он будет проверять оба в node_moudles на наличие файла или папки с именем Todo, и он будет проверять app/components на наличие папки.

Если вы хотите использовать тот же трюк с разрешением в своих тестах, вам нужно создать тестовый пакет с Webpack и запустить этот пакет так же, как вы создаете пакет браузера.

В противном случае вы должны использовать способ Node по умолчанию, чтобы требовать файлы не в node_modules, то есть с относительными путями:

const TodoList = require('../../components/TodoList');
const Todo = require('../../components/Todo');
0
Andy Ray 27 Ноя 2016 в 04:14

Альтернативно :

const TodoList = require('TodoList').default;
const Todo = require('Todo').default;
1
Yadhu Kiran 27 Ноя 2016 в 04:13