6

我正在尝试测试使用React 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 });

测试代码(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,因此没有断言有效。

另外我想提出这样一个事实,即这只在测试中失败,组件在 Web 应用程序生成的 html 代码中生成预期的 html 类。

知道如何解决这个问题吗?

更新

正如 fabio 在评论中所建议的那样,我试图删除该选项errorWhenNotFound: false

现在测试给出以下错误信息:

错误:“bar”CSS 模块未定义。

我不明白,因为 bar 类是在Foo.css文件中定义的。

我还发现,如果我调试Foo组件中的样式:

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

它返回一个空输出:

风格{}

尽管在这个简化的示例和完整的代码中,组件都会在 Web 应用程序生成的 html 代码中生成预期的 html 类,并且相应的样式可以正常工作。

4

2 回答 2

11

正如评论中的 OP 所述,问题在于 Mocha 正在使用 ignore-styles 选项运行。这与该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
})

在你的 Mocha 入口文件中(在你做任何其他事情之前),告诉它如何处理 css/sass 文件。

例如,您可以将该要点的内容放在 test/setup.js 文件中,然后以这种方式运行 Mocha:

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

这样,您的 setup.js 初始化代码将在测试之前运行。

于 2016-10-11T10:23:49.397 回答
0

感谢你的回答!如果你不关心 SASS,你也可以这样做......

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

hook({
  generateScopedName: '[local]___[hash:base64:5]',
})
于 2017-01-10T12:07:03.990 回答