admin管理员组

文章数量:1336089

It is my first time with testing JS frontend and I chose mocha for that.
I have a class let us say Market which uses other classes I made.
I use import ... from ... clause and export default Market in the end.

so Market class looks like that:

import { math, AnotherClass, MyOtherClass } from '../index.js'
class Market {
  constructor () {
    // code here
  }
  methodToTest(input) {
    // some code here ...
    return output
  }
}
export default Market

and then my test.js

var assert = require('assert')
// import { Market } from '../public/mm/ai/Market.js'
var Market = require('../public/mm/ai/Market')

describe('Market', function() {
    describe('#methodToTest()', function() {
        it('should return 0 input is greater than mean + 4 * sigma', function() {
           var market = new Market()
           assert.equal(market.methodToTest(45), 0)
        })
    })
})

and after running the test I get the error:

import { math, AnotherClass, MyOtherClass } from '../index.js'
^^^^^^

SyntaxError: Cannot use import statement outside a module

and an error stack.

And the question is: How to make mocha test my modules with these imports?
As you see I also tried to use import directly in test.js and it failed also. But I don't want to rewrite my whole project to use require as it works perfectly fine in the browser as it is now.

It is my first time with testing JS frontend and I chose mocha for that.
I have a class let us say Market which uses other classes I made.
I use import ... from ... clause and export default Market in the end.

so Market class looks like that:

import { math, AnotherClass, MyOtherClass } from '../index.js'
class Market {
  constructor () {
    // code here
  }
  methodToTest(input) {
    // some code here ...
    return output
  }
}
export default Market

and then my test.js

var assert = require('assert')
// import { Market } from '../public/mm/ai/Market.js'
var Market = require('../public/mm/ai/Market')

describe('Market', function() {
    describe('#methodToTest()', function() {
        it('should return 0 input is greater than mean + 4 * sigma', function() {
           var market = new Market()
           assert.equal(market.methodToTest(45), 0)
        })
    })
})

and after running the test I get the error:

import { math, AnotherClass, MyOtherClass } from '../index.js'
^^^^^^

SyntaxError: Cannot use import statement outside a module

and an error stack.

And the question is: How to make mocha test my modules with these imports?
As you see I also tried to use import directly in test.js and it failed also. But I don't want to rewrite my whole project to use require as it works perfectly fine in the browser as it is now.

Share Improve this question asked Feb 14, 2020 at 13:29 GeorgeGeorge 891 silver badge8 bronze badges 4
  • Your tests also need to run through Babel. – Dave Newton Commented Feb 14, 2020 at 13:31
  • 1 But I was trying to test the class as it is before translating through Babel. – George Commented Feb 14, 2020 at 13:35
  • 1 OK, so I guess I don't get this whole mess of JS tools. – George Commented Feb 17, 2020 at 11:42
  • Wele to the club. It also depends if you're running the tests in the browser or from the mand line--but bottom line is that the tests also need to be babelized. – Dave Newton Commented Feb 17, 2020 at 15:57
Add a ment  | 

2 Answers 2

Reset to default 6

For anyone who suffer from configuration

1. installation

You need to install mocha and @babel/XXX plugins

npm install mocha --save-dev
npm install @babel/cli @babel/core @babel/preset-env @babel/register --save-dev

Check the package.json. It might be like this

{
  "scripts": { ... }
  "devDependencies": {
    "@babel/cli": "^7.15.7",
    "@babel/core": "^7.15.5",
    "@babel/preset-env": "^7.15.6",
    "@babel/register": "^7.15.3",
    ...
    "mocha": "^9.1.2",
    ...
  },
  ...
}  
  • Version can be different

2. babel configuration

create babel configuration file .babelrc under the [PROJECT-ROOT]

[PROJECT-ROOT]
 +- src
 +- test
 +- package.json
 +- .babelrc (+)

And fill the content like this

{
  "presets": ["@babel/preset-env"]
}

3. test script runner

open package.json and find "scripts" block

{
  "name": "...",
  ...
  "scripts": {
     "build": ...,
     "start": ...,
  },
}

create "test" property with value mocha --require @babel/register

{
  "name": "...",
  ...
  "scripts": {
     "build": ...,
     "start": ...,
     "test": "mocha --require @babel/register"
  },
}

4. Samples

create a file(calc.js) to be tested, and test file(calc.spec.js)

[PROJECT-ROOT]
 +- src
     +- calc.js      (+)
 +- test
     +- calc.spec.js (+)
 +- package.json
 +- .babelrc
// calc.js
const add = (a, b) => a + b
const mul = (a, b) => a * b

export default {
  add,
  mul
}

and test file calc.spec.js

// calc.spec.js
const assert = require('assert')
import calc from '../src/calc'

describe('testing calc.add, cal.mul', () => {
  it('should be seven', () => {
    const seven = calc.add(3, 4)
    assert.equal(7, seven)
  })
})

5. running test

input the npm run test in console

$ npm run test

  testing calc.add, cal.mul
    ✔ should be seven


  1 passing (7ms)

6. Reference

  • https://github./mochajs/mocha-examples/tree/master/packages/babel

So I have found the solution myself.

  1. Babel & mocha - the best, cause no intermediate files

First the .mocharc.js file to configure mocha to use babel and chai:

module.exports = {
    require: ['chai', '@babel/register'],
    ui: 'bdd',
    // ui: 'tdd',
    reporter: 'spec',
    growl: false,
};

I have chosen ui:'bdd' because I used the describe in test.js: describe('Market class:', function() {

Secondly I added babel configuration in package.json:

"babel": {
    "env": {
      "test-console": {
        "presets": ["@babel/preset-env"],
        "plugins": ["@babel/plugin-proposal-class-properties"]
      }
    ,
      "test": {
        "presets": ["@babel/preset-env"],
        "plugins": ["@babel/plugin-proposal-class-properties", "transform-remove-console"]
      }
    }
  },

Two environments to use with console output and wituhout it.
It leads to package.json scripts section to execute one of them:

 "scripts": {
    "test": "BABEL_ENV=test mocha || TRUE",
    "test-console-log": "BABEL_ENV=test-console mocha || TRUE"
  },

and now I was ready to have my test.js executed and imports in my modules worked.
Here is the head of test.js:

var assert = require('chai').assert
import Market from '../public/mm/ai/Market.js'
...

I switched to import when regarding my own modules.

  1. Webpack, babel & mocha

Everything in webpack config:

var path = require('path');
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
  mode: 'none',
  entry: './test/test.js',
  output: {
      path: path.resolve(__dirname, 'test/'),
      filename: 'exec_test.js'
  },
  module: {
    rules: [
        {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                    plugins: ['@babel/plugin-proposal-class-properties']
                }
            }
        }
    ]
  },
  optimization: {
      minimize: true,
      minimizer: [new TerserPlugin({
          terserOptions: {
              press: 
              {
                  drop_console: true
                }
            }
        })]
    }
};

and then you can build and run it by:

"scripts": {
   "build-tests-webpack": "webpack --config webpack.config.test.js",
   "exec test": "mocha --ui bdd test/exec_test.js"
}

in package.json

本文标签: javascriptHow to test ES6 modules (these with import) with mochaStack Overflow