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.
- 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
2 Answers
Reset to default 6For 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.
- 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.
- 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