【问题标题】:Test with Mocha and Enzyme a React component that uses React CSS Modules使用 Mocha 和 Enzyme 测试使用 React CSS 模块的 React 组件
【发布时间】:2017-02-12 14:52:43
【问题描述】:

我正在尝试测试使用React CSS modules的组件的生成类

这是一个示例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 类,并且相应的样式可以正常工作。

【问题讨论】:

  • 如果您使用的是 webpack,您是否有忽略导入的 css 文件的特定于测试的配置/加载器?可能是 CSSModules 没有找到该类名,并且 errorWhenNotFound: false 忽略了该错误(您也可以尝试将其删除以帮助调试问题)。
  • 所以现在我们至少知道为什么您在输出中看不到类。我仍然认为您有一些与测试相关的配置或代码忽略了 css 文件的内容,例如:npmjs.com/package/ignore-styles,这在测试中很常见。您可以发布您用于测试的完整 webpack 配置吗?您是否使用 mocha 作为测试运行程序?您是否尝试做与此 github.com/airbnb/enzyme/issues/202 相关的任何事情?
  • 我认为你中了大奖! Mocha 正在使用ignore-styles 选项执行,现在已修复此问题,正在生成以下错误消息:SyntaxError: /var/www/web/app/components/Icon.css: Leading decorators must be attached to a class declaration 但至少现在这是一个不同的问题。
  • 很高兴为您提供帮助,我添加了一个包含更多详细信息的答案。

标签: unit-testing reactjs mocha.js enzyme react-css-modules


【解决方案1】:

正如 cmets 中的 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
})

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

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

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

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

【讨论】:

  • 什么是摩卡入口?
  • @angrykiwi 我的意思是你在运行实际测试之前使用 mocha 需要的文件(因此“入口点”中的“入口点”)。请参阅我帖子中的最后一个命令,我将两个文件路径传递给 --require 标志。第一个是我所说的“入口”,第二个是包含所有实际测试文件的全局。您希望 setup.js 中的代码先运行,这样您就可以指导 mocha 如何编译您的测试代码所需的 sass 文件。
  • 你有完全集成的 react && css 模块和 mocha 测试的例子吗?
  • 谢谢!它真的拯救了我的一天
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 2018-07-23
    • 2018-08-20
    • 2017-04-13
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多