2016-10-04 2 views
6

Я пытаюсь проверить сгенерированный класс компонента, который использует React CSS modulesТест с мокко и ферментным РЕАКТОМ компонента, который использует Реагировать модули CSS

Вот пример Foo компонент:

import React from 'react'; 
import CSSModules from 'react-css-modules'; 
import styles from './Foo.css'; 

const Foo = ({ className }) => <div styleName={className} />; 

Foo.propTypes = { 
    className: React.PropTypes.string.isRequired, 
}; 

export default CSSModules(Foo, styles, { allowMultiple: true, errorWhenNotFound: false }); 

Test код (Foo.spec.jsx):

import React from 'react'; 
import { expect } from 'chai'; 
import { shallow } from 'enzyme'; 
import Foo from '../../../app/components/Foo'; 

describe('<Foo/>',() => { 
    it.only('should return a className prop as class value',() => { 
     const wrapper = shallow(<Foo className="bar" />); 
     console.log('DEBUG----->', wrapper.html()); 
    }); 
}); 

Foo.css код:

.bar { 
    background-color: red; 
} 

А вот тест HTML выход:

DEBUG-----> <div></div> 

Как вы можете видеть, что это создает пустой DIV без какого-либо класса, так что ни утверждение не работает.

Также я хотел бы рассказать о том, что это только терпит неудачу в тестировании, компонент генерирует ожидаемый класс html в созданном веб-приложении html-коде.

Любая идея, как исправить это?

UPDATE

Как было предложено в комментарии по Fabio Я попытался удалить опцию errorWhenNotFound: false

Теперь тест дает следующее сообщение об ошибке:

Error: "bar" CSS module is undefined.

Что я дон Не понимаю, поскольку класс bar определен в файле Foo.css.

Также я обнаружил, что если я отлаживать стили в Foo компонента:

import styles from './Foo.css'; 
console.log('STYLES', styles); 

Она возвращает пустой результат:

STYLES {}

Хотя и в этом упрощенном примере, так и в полной мере он генерирует ожидаемый класс html в созданном веб-приложении html-коде, при этом соответствующие стили работают нормально.

+1

Если вы используете Webpack, у вас есть тест конкретной конфигурации/погрузчики, игнорирующие импортированные файлы CSS? Возможно, CSSModules не находит это имя класса, и ошибка игнорируется '' 'errorWhenNotFound: false''' (который вы также можете попытаться удалить, чтобы помочь отладить проблему). –

+1

Итак, теперь мы хотя бы знаем, почему вы не видите класс на выходе. Я все еще думаю, что у вас есть какая-то связанная с тестированием конфигурация или код, который игнорирует содержимое файла css, примерно так: https://www.npmjs.com/package/ignore-styles, который довольно часто используется в тестах. Можете ли вы опубликовать полную конфигурацию webpack, которую вы используете для тестов? Используете ли вы мокко как тест-бегун? Вы пытаетесь сделать что-либо, связанное с этим https://github.com/airbnb/enzyme/issues/202? –

+0

Я думаю, вы попали в джек-пот !. Mocha выполнялось с опцией «игнорировать-стили», теперь, когда это исправлено, генерируется следующее сообщение об ошибке: «SyntaxError: /var/www/web/app/components/Icon.css: должны быть прикреплены ведущие декораторы к объявлению класса Но по крайней мере сейчас это другая проблема. – rfc1484

ответ

10

Как указано в комментариях к OP, проблема заключается в том, что Mocha работал с опцией игнорирования стилей. Это, вместе с опцией errorWhenNotFound: false, маскировало актуальную проблему, которая заключается в том, что объект стиля, экспортируемый модулем, фактически пуст, а модуль игнорируется Mocha.

Без этой опции вам все равно необходимо указать Mocha для импорта модуля CSS и правильного его анализа. Ошибка объявления /var/www/web/app/components/Icon.css: Leading decorators must be attached to a class, вероятно, связана с тем, что Mocha пытается интерпретировать содержимое файла css как js, что, очевидно, не удается.

Чтобы правильно установить вещи, посмотрите здесь: https://gist.github.com/mmrko/288d159a55adf1916f71

Идея заключается в том, чтобы сделать что-то вроде этого:

var hook = require('css-modules-require-hook') 
var sass = require('node-sass') 

hook({ 
    extensions: [ '.scss', '.css' ], 
    generateScopedName: '[local]___[hash:base64:5]', 
    preprocessCss: (data, file) => sass.renderSync({ file }).css 
}) 

в файле ввода Мокко (прежде чем делать что-нибудь еще), вам расскажут, как обрабатывать файлы css/sass.

Вы можете поместить содержимое этой сущности внутри тестовой/setup.js файл, например, а затем запустить Mocha таким образом:

mocha --compilers js:babel-register --require ./test/setup.js \"./test/**/*.spec.js\" 

В этом случае ваш setup.js код инициализации будет работать перед испытаниями.

+0

Что такое запись мокко? –

+0

@angrykiwi Я имею в виду файл, который вам нужен с моккой, прежде чем запускать фактические тесты (отсюда «запись», как в «точке входа»). Посмотрите последнюю команду в моем сообщении, я передаю два пути к файлу --require. Во-первых, это то, что я назвал «entry», второй - glob для включения всех фактических тестовых файлов. Вы хотите, чтобы код в setup.js запускался раньше всего, чтобы вы могли указать мокко, как скомпилировать файлы sass, необходимые для вашего тестируемого кода. –

+0

Есть ли у вас пример полностью интегрированного модуля && css и тестирования с мокко? –

0

Спасибо за ответ! Если вы не связан с SASS вы можете просто сделать это ...

import hook from 'css-modules-require-hook' 

hook({ 
    generateScopedName: '[local]___[hash:base64:5]', 
})