Mokka-Test fehlgeschlagen aufgrund von CSS im Webpack

73

Ich bin neu in Mocha und versuche damit eine einfache React-Komponente zu testen. Der Test wird bestanden, wenn die Reaktionskomponente kein CSS-Design hat, aber einen Syntaxfehler auslöst, wenn das Tag in der Reaktionskomponente einen Klassennamen enthält:

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

Der Test würde bestehen:

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

Nachdem ich den Klassennamen in das Eingabe-Tag eingefügt habe, wird ein Fehler angezeigt:

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

Testergebnis:

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

Ich habe online gesucht, aber bisher kein Glück. Vermisse ich etwas Bitte helfen Sie mir oder weisen Sie mich in die richtige Richtung. Wir würden uns sehr freuen. Ich verwende derzeit:
Node Express Server
React
React-Router
Webpack
Babel
Mokka
Chai
Sinon
Sinon-Chai

Yi Ren
quelle
Haben Sie versucht, ein Webpack-Paket zu benötigen? github.com/petehunt/webpack-require
ctrlplusb

Antworten:

150

Es gibt einen babel/registerStil-Hook, mit dem Stilimporte ignoriert werden können:

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

Es installieren:

npm install --save-dev ignore-styles

Führen Sie Tests ohne Stile aus:

mocha --require ignore-styles

rzueger
quelle
1
Das rettet meinen Tag. Und dieses Update funktioniert auch für Istanbul. Vielen Dank!
Lazyy
4
Was ist, wenn ich auch meine Stile testen möchte?
Kapuziner
Es gibt ein Kernstück hier, aber ich konnte es nicht dazu bringen, mit dem Webpack zu arbeiten. ~ Imports - gist.github.com/ryanseddon/e76fd16af2f8f4f4bed8
Jon Freedman
12

Sie können einen CSS-Compiler verwenden, der Mokka ausführt. Der Compiler js lautet wie folgt:

css-dnt-compiler.js

function donothing() {
  return null;
}

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

und führen Sie den Mokka-Befehl folgendermaßen aus:

mocha --compilers js:babel-core/register,css:css-dnt-compiler.js --recursive
Zhaozhiming
quelle
1
Diese Lösung hat bei mir funktioniert. Sie müssen nur sicherstellen, dass Sie den richtigen Pfad zur css-dnt-compilerDatei angeben. In meinem Fall habe ich ihn also im testOrdner gespeichert , sodass der Befehl wie folgt lautet :mocha --compilers js:babel-core/register,css:test/css-dnt-compiler.js --recursive
Marcos Abreu
etwas einfacher, require.extensions['.scss'] = ()=>null; require.extensions['.css'] = ()=>null;aber diese Antwort war perfekt
Kevin Danikowski
8

Meine gleiche Antwort wie hier , das ist es, was ich verwendet habe, um an Babel 6 zu arbeiten

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;

Auf diese Weise können Sie Ihre Tests neben Ihren Komponenten in Ihrem src-Ordner ablegen. Mit require.extensions können Sie beliebig viele Erweiterungen hinzufügen.

Mummybot
quelle
1
wenn noop()kehrt {}stattdessen können Sie es auch zu Mock Klassennamen verwenden. Wenn Sie beispielsweise verwendet haben import styles from 'my.css', können Sie dies styles.myClassNamein Ihrer Testsuite festlegen , und Ihre Reaktionskomponente, die auf dasselbe CSS-Modul verweist, sieht diese Werte. Dies ist sehr nützlich, wenn Klassenselektoren in Test-Frameworks wie Enzyme
Killthrush
Funktioniert gut. Ich habe alle Mokka-Optionen auf mocha.opts verschoben, um Skripte sauber zu machen.
evgeny.myasishchev
4

Da Sie mit webpack, Verwendung null-Lader zu laden , nullwenn webpack eine erforderliche CSS trifft / LESS / SASS / etc Datei in Ihren Komponenten. Installieren Sie über npm und aktualisieren Sie dann Ihre Webpack-Konfiguration, um den Loader einzuschließen:

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

Dies verhindert natürlich, dass Sie CSS in Ihre eigentliche Anwendung laden. Daher sollten Sie eine separate Webpack-Konfiguration für Ihr Testpaket haben, das diesen Loader verwendet.

Jim Skerritt
quelle
Ich habe es versucht, es scheint nicht zu funktionieren. Außerdem habe ich festgestellt, dass der Fehler nicht durch das Hinzufügen von className zu den Komponenten verursacht wird. Es ist Ursache durch den Import von CSS-Datei: import testingStyle from '../../scss/components/landing/testing.scss';
Yi Ren
1

Keine dieser Lösungen hat bei mir funktioniert, da ich Mokka-Webpack verwende und der Schalter "--compiler" nicht akzeptiert wird. Ich habe das Ignorierstil-Paket implementiert, wie in der beliebtesten Antwort beschrieben, aber es schien träge zu sein, ohne Unterschied in meinem Istanbul-Bericht (.less-Dateien werden noch getestet).

Das Problem ist der .less-Loader, den ich in meiner Datei webpack.config.test.js verwendet habe. Das einfache Austauschen von Less-Loader gegen Null-Loader hat mein Problem behoben.

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

Für mich ist dies bei weitem die einfachste Lösung und zielt direkt auf meine Testkonfiguration ab, anstatt die package.json-Skripte ändern / hinzufügen oder, schlimmer noch, neue .js-Dateien hinzufügen zu müssen.

Artif3x
quelle
Mir scheint, dies ist die gleiche Lösung wie vor zwei Jahren von Jim Skerritt : Ersetzen Sie Ihren Lader durch null-loader.
Louis
1

Für diejenigen, die damit umgehen jestmöchten, fügen Sie einfach einen Handler für Stildateien hinzu:

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

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

Mehr hier .

Piotr Jaworski
quelle
0

Eine einfache Möglichkeit besteht darin, "Ignorierstile" zu importieren. in deinen Testklassen ..

Neelendu Shekhar
quelle
0

Der folgende Code funktioniert ohne Abhängigkeiten. Fügen Sie es einfach oben in die Tests ein.

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);
};
bert
quelle
0

Obwohl diese Frage sehr alt ist, ist sie immer noch relevant. Lassen Sie mich also eine andere Lösung einbringen.

Verwenden Sie Piraten , ein Paket, dem Sie Hooks hinzufügen können require()- wenn Sie Babel verwenden, haben Sie es bereits.

Beispielcode:

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

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

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

Auf diese Weise können Sie Mokka so nennen: mocha --require .test-init.js [whatever other parameters you use]

Dies ist unkompliziert, elegant und bedeutet im Gegensatz zu Ignorierstilen nicht, dass Sie nur Stile ignorieren. Dies ist auch leicht erweiterbar, wenn Sie bei Ihren Tests weitere Tricks anwenden müssen, z. B. das Verspotten ganzer Module.

AlQafir
quelle