由于 webpack 中的 css,摩卡测试失败

我是新来的摩卡,我试图用它来测试一个简单的反应组件。如果 React 组件没有任何 CSS 样式,但是如果 React 组件中的标记包含任何 className,则会抛出语法错误,测试将通过:

Testing.react.js

import React from 'react';


export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" />
</form>
</section>
);
}
}

测试 jsx

import {
React,
sinon,
assert,
expect,
TestUtils
} from '../../test_helper';


import TestingSample from '../../../app/components/Testing.react.js';


describe('TestingSample component', function(){
before('render and locate element', function(){
var renderedComponent = TestUtils.renderIntoDocument(
<TestingSample />
);


var inputComponent = TestUtils.findRenderedDOMComponentWithTag(
renderedComponent, 'input'
);


this.inputElement = inputComponent.getDOMNode();
});


it('<input> should be of type "text"', function () {
assert(this.inputElement.getAttribute('type') === 'text');
});
})

测试将通过:

> mocha --opts ./test/javascripts/mocha.opts --compilers js:babel/register --recursive test/javascripts/**/*.jsx




TestSample component
✓ <input> should be of type "text"




1 passing (44ms)

在我将 className 添加到 input 标记中之后,出现了一个错误:

import React from 'react';
import testingStyle from '../../scss/components/landing/testing.scss';


export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" className="testingStyle.color" placeholder="Where would you like to dine" />
</form>
</section>
);
}
}

测试结果:

SyntaxError: /Users/../../../Documents/project/app/scss/components/landing/testing.scss: Unexpected token (1:0)
> 1 | .color {
| ^
2 |   color: red;
3 | }

我已经在网上搜索过了,但是目前还没有结果。我错过了什么吗?请帮助我或指出我的正确方向将不胜感激。 我现在使用:
节点快递服务器
做出反应
反应路由器
网络包
巴别塔
摩卡
阿漆
西农
Sinon-Chai

19562 次浏览

Since you're using webpack, use null-loader to load null when webpack encounters a required CSS/LESS/SASS/etc file in your components. Install via npm and then update your webpack config to include the loader:

{
test: /(\.css|\.less|.\scss)$/,
loader: 'null-loader'
}

Obviously this will prevent you from loading CSS in your actual application, so you'll want to have a separate webpack config for your test bundle that uses this loader.

you can use a css compilers run mocha, the compiler js as follow:

css-dnt-compiler.js

function donothing() {
return null;
}


require.extensions['.css'] = donothing;
require.extensions['.less'] = donothing;
require.extensions['.scss'] = donothing;
// ..etc

and run the mocha command like this:

mocha --compilers js:babel-core/register,css:css-dnt-compiler.js --recursive

There is a babel/register style hook to ignore style imports:

https://www.npmjs.com/package/ignore-styles

Install it:

npm install --save-dev ignore-styles

Run tests without styles:

mocha --require ignore-styles

My same answer as here, this is what I used to get working on Babel 6

package.json

"scripts": {
"test": "mocha --compilers js:babel-core/register
--require ./tools/testHelper.js 'src/**/*-spec.@(js|jsx)'",

tools/testHelper.js

// Prevent mocha from interpreting CSS @import files
function noop() {
return null;
}


require.extensions['.css'] = noop;

This enables you to have your tests inside your src folder alongside your components. You can add as many extensions as you would like with require.extensions.

None of these solutions worked for me, as I'm using mocha-webpack, and it doesn't accept the "--compilers" switch. I implemented the ignore-styles package, as described in the most popular answer, but it seemed inert, with no difference in my Istanbul coverage report (.less files still being tested).

The problem is the .less loader that I was using in my webpack.config.test.js file. Simply swapping less-loader for null-loader fixed my problem.

module: {
rules: [
{
test: /\.less$/,
use: ['null-loader']
}
]
}

For me, this is by far the simplest solution, and targets my testing configuration directly, rather than having to alter/add to the package.json scripts, or worse, add new .js files.

One simple way is to import 'ignore-styles'; in your test classes..

For those looking how to handle this in jest - you just add a handler for style files:

// package.json
{
"jest": {
"moduleNameMapper": {
"\\.(css|less|scss|sass)$": "<rootDir>/__mocks__/styleMock.js"
}
}
}


// __mocks__/styleMock.js
module.exports = {};

More here.

The code below works without any dependencies. Just add it to the top of the tests.

var Module = require('module');
var originalRequire = Module.prototype.require;
Module.prototype.require = function () {
if (arguments[0] && arguments[0].endsWith(".css"))
return;
return originalRequire.apply(this, arguments);
};

Although very old, this question is still relevant, so let me throw in another solution.

Use pirates, a package to add hooks to require() - if you use Babel, you already have it.

Example code:

// .test-init.js
const { addHook } = require('pirates');


const IGNORE_EXTENSIONS = ['.scss', '.svg', '.css'];


addHook((code, filename) => '', { exts: IGNORE_EXTENSIONS });

This way you can call mocha like so: mocha --require .test-init.js [whatever other parameters you use]

This is straightforward, elegant and unlike ignore-styles it doesn't imply you are ignoring styles only. Also, this is easily extendable if you need to apply some more trickery to your tests like mocking entire modules.