使用 Mocha 和 Enzyme 测试一个使用 React CSS 模块的 React 组件

Test with Mocha and Enzyme a React component that uses React CSS Modules

我正在尝试测试使用 React CSS modules

的组件生成的 class

这是一个示例 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>

如您所见,它生成了一个没有任何 class 的空 div,因此断言无效。

此外,我想提出一个事实,即这仅在测试中失败,组件在网络应用程序生成的 html 代码中生成预期的 html class。

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

更新

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

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

Error: "bar" CSS module is undefined.

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

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

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

它returns一个空输出:

STYLES {}

虽然在这个简化的示例和完整的代码中组件生成了预期的 html class 在 Web 应用程序生成的 html 代码中,相应的样式工作正常。

正如 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 初始化代码将 运行 在测试之前。

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

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

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