使用 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]',
})
我正在尝试测试使用 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]',
})