15

When testing .js files that have Webpack CSS imports like import './style.css', Mocha throws a syntax error (because it tries to import and parse the CSS file as JS). There is a solution for this that has already been posted on Stack Overflow, but it only addresses if you aren't already using a compiler with Mocha. I'm using Babel 5. I've tried the following, but it seems that Mocha doesn't support passing multiple compilers:

// npm test script

mocha ./src/**/*Test.js --compilers css:./scripts/mocha-webpack-compiler.js js:babel/register

// scripts/mocha-webpack-compiler.js

function noop() {
  return null;
}

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

Is there a way to have multiple Mocha compilers, or a better way to tell Mocha not to try to parse Webpack CSS imports?


EDIT:

I like the proposed solution by @Giles B below; it was exactly what I needed. However, since I am still on Babel 5 I needed a few tweaks as shown below:

mocha.opts

--require scripts/support/babelhook
--require scripts/support/mocha-webpack-compiler

scripts/babelhook.js

require('babel/register');

scripts/mocha-webpack-compiler.js

function noop() {
    return null;
}
require.extensions['.css'] = noop;

mocha script

mocha ./src/**/*Test.js

This is working for me using babel and babel-core, both version 5.8.23.

Community
  • 1
  • 1

2 Answers2

15

I came across the same problem and just got it working, so in my mocha.opts file I added the following require calls:

--require test/babelhook
--require test/css-null-compiler

In babelhook.js I have one require statement to load babel:

// This file is required in mocha.opts
// The only purpose of this file is to ensure
// the babel transpiler is activated prior to any
// test code, and using the same babel options

require("babel-register")();

Then from the link you provided I setup css-null-compiler.js as follows:

// Prevent Mocha from compiling class
function noop() {
  return null;
}

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

Hope that helps.

Community
  • 1
  • 1
Giles Butler
  • 971
  • 3
  • 14
  • 23
  • Thank you - this looks to be exactly what I need. But, it isn't working for me yet: I'm getting a "SyntaxError: Unexpected token import"; are you using ES6 modules? Btw, I am still on Babel 5 (babel 6 had too many issues currently). Related SO question: http://stackoverflow.com/questions/20049790/how-to-pass-compiler-options-to-mocha –  Dec 09 '15 at 05:01
  • I've also added a bounty of 100 reputation if you or anyone else can help me get this working –  Dec 09 '15 at 05:13
  • Hey @trevordmiller, sorry for the late reply. Yes I'm using Babel 6 so maybe that is where the problem is. I'm testing ES6 modules but the code above isn't ES6. – Giles Butler Dec 10 '15 at 16:35
  • I think require("babel-register")(); is only for Babel 6, you need require("babel/register"); for version 5. – Giles Butler Dec 10 '15 at 16:40
  • 1
    I tried using require('babel/register'); instead, but I'm getting the same error. –  Dec 10 '15 at 19:34
  • 1
    I think I may have solved it - I didn't realize that mocha.opts needed to be in /test/ in order to be recognized (I had it in the root of the project). I will do more testing and get back; if it is working, I will award the bounty points to you Giles. –  Dec 10 '15 at 19:40
  • 1
    Now I am getting the `SyntaxError: Unexpected token import` error again, but for a different reason; it looks like `babel/register` doesn't work with import statements inside of `node_modules/` packages. Odd, because all of my tests were working with the `--compilers` option from the direct CLI. I'm not sure what to do now. I could use the Webpack --target node option in the webpack docs, but I would prefer to have my tests work without any dependency on Webpack. –  Dec 10 '15 at 19:56
  • 1
    This is an unrelated problem - it is working for what I asked, so I will award Giles the bounty. Thanks Giles! –  Dec 10 '15 at 21:40
  • Note that you don't need mocha.opts. And you don't need two separate files either. You could simply call a single file from the command line which contains both the babel and null compiler code. Here's how I solved it: https://github.com/coryhouse/react-slingshot/blob/master/package.json#L18 – Cory House Apr 08 '16 at 20:45
5

Based on @Giles' answer above, 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.

mummybot
  • 2,668
  • 2
  • 28
  • 31