由于Webpack中的CSS,Mocha测试失败


73

我是Mocha的新手,我正在尝试使用它来测试一个简单的React组件。如果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>
    );
  }
}

testing.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之后,出现错误:

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 | }

我已经在网上搜索过,但到目前为止还没有运气。我想念什么吗?请帮助我或指出正确的方向,将不胜感激。我当前正在使用:
Node Express Server
React
React-router
Webpack
Babel
Mocha
Chai
Sinon
Sinon-Chai


您是否尝试过webpack-require软件包?github.com/petehunt/webpack-require
ctrlplusb

Answers:


151

有一个babel/register样式挂钩可忽略样式导入:

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

安装它:

npm install --save-dev ignore-styles

运行没有样式的测试:

mocha --require ignore-styles


1
这可以节省我的时间。而且此修复程序也适用于伊斯坦布尔。谢谢!
lazurey

4
如果我也想测试我的样式怎么办?
Capuchin

这里有一个要点,但是我无法使它与Webpack友好〜导入-gist.github.com/ryanseddon/e76fd16af2f8f4f4bed8
Jon Freedman

12

您可以使用css编译器运行mocha,将js编译器如下:

css-dnt-compiler.js

function donothing() {
  return null;
}

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

并像下面这样运行mocha命令:

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

1
此解决方案为我工作,您唯一需要确保的是您包括css-dnt-compiler文件的正确路径,因此,就我而言,我将其存储在test文件夹中,因此命令变为:mocha --compilers js:babel-core/register,css:test/css-dnt-compiler.js --recursive
Marcos Abreu

稍微简单一点,require.extensions['.scss'] = ()=>null; require.extensions['.css'] = ()=>null;但是这个答案很完美
Kevin Danikowski

8

我和这里的答案相同,这就是我以前从事Babel 6的工作

package.json

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

工具/testHelper.js

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

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

这使您可以将测试与组件一起放在src文件夹中。您可以使用require.extensions添加任意数量的扩展名。


1
如果noop()返回{}return,则还可以使用它来模拟类名。因此,例如,如果您使用import styles from 'my.css',则可以styles.myClassName在测试套件中进行设置,引用相同CSS模块的react组件将看到这些值。当在诸如Enzyme
killthrush

效果不错。我已将所有摩卡选项移至mocha.opts以使脚本更干净。
evgeny.myasishchev

4

由于您使用的是webpack,因此当webpack在组件中遇到所需的CSS / LESS / SASS / etc文件时,请使用null-loader进行加载null。通过npm安装,然后更新您的webpack配置以包括加载程序:

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

显然,这将阻止您在实际的应用程序中加载CSS,因此您将需要为使用该加载器的测试包提供一个单独的webpack配置。


我尝试过,它似乎不起作用。另外,我注意到该错误不是由将className添加到组件引起的。这是由于导入CSS文件引起的: import testingStyle from '../../scss/components/landing/testing.scss';
Yi Ren

1

这些解决方案都不适合我,因为我正在使用mocha-webpack,并且不接受“ --compilers”开关。如最受欢迎的答案所述,我实现了ignore-styles程序包,但它似乎是惰性的,在我的Istanbul覆盖率报告中没有任何区别(.less文件仍在测试中)。

问题是我在webpack.config.test.js文件中使用的.less加载程序。只需将less-loader替换为null-loader解决了我的问题。

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

对我而言,这是迄今为止最简单的解决方案,直接针对我的测试配置,而不必更改/添加到package.json脚本,或者更糟的是添加新的.js文件。


在我看来,这与两年前吉姆·斯凯里特Jim Skerritt)发布的解决方案相同:用替换您的装载机null-loader
路易(Louis)

1

对于那些希望如何处理此问题的人,jest您只需为样式文件添加处理程序即可:

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

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

这里更多。



0

下面的代码可以不依赖任何代码地工作。只需将其添加到测试的顶部即可。

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);
};

0

尽管这个问题很老,但仍然很重要,因此让我提出另一个解决方案。

使用pirates(向其添加钩子的软件包)require()-如果您使用Babel,则已经拥有它。

示例代码:

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

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

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

这样,您可以像这样调用mocha: mocha --require .test-init.js [whatever other parameters you use]

这是直接,优雅的,并且与忽略样式不同,这并不意味着您只在忽略样式。另外,如果您需要对测试应用更多技巧,例如模拟整个模块,则可以轻松扩展此方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.