Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use ES6 modules in Mocha tests?

ES6, Windows 10 x64, Node.js 8.6.0, Mocha 3.5.3

Is it possible to use ES6 modules in Mocha tests? I have the problems with export and import keywords.

/* eventEmitter.js
 */

/* Event emitter. */
export default class EventEmitter{

    constructor(){

        const subscriptions = new Map();

        Object.defineProperty(this, 'subscriptions', {
            enumerable: false,
            configurable: false,
            get: function(){
                return subscriptions;
            }
        });
    }

    /* Add the event listener.
     * @eventName - the event name. 
     * @listener - the listener.
     */
    addListener(eventName, listener){
        if(!eventName || !listener) return false;
        else{
            if(this.subscriptions.has(eventName)){
                const arr = this.subscriptions.get(eventName);
                arr.push(listener);
            }
            else{
                const arr = [listener];
                this.subscriptions.set(eventName, arr);
            }
            return true;
        }
    }

    /* Delete the event listener.
     * @eventName - the event name. 
     * @listener - the listener.
     */
    deleteListener(eventName, listener){
        if(!eventName || !listener) return false;
        else{
            if(this.subscriptions.has(eventName)){
                const arr = this.subscriptions.get(eventName);
                let index = arr.indexOf(listener);

                if(index >= 0){
                    arr.splice(index, 1);
                    return true;
                }
                else{
                    return false;
                }
            }
            else{
                return false;
            }
        }
    }

    /* Emit the event.
     * @eventName - the event name. 
     * @info - the event argument.
     */
    emit(eventName, info){
        if(!eventName || !this.subscriptions.has(eventName)) {
            return false;
        }
        else{
            for(let fn of this.subscriptions.get(eventName)){
                if(fn) fn(info);
            }
            return true;
        }
    }
}

Mocha test:

/* test.js 
 * Mocha tests.
 */
import EventEmitter from '../../src/js/eventEmitter.js';

const assert = require('assert');

describe('EventEmitter', function() {
  describe('#constructor()', function() {
    it('should work.', function() {
        const em = new EventEmitter();
        assert.equal(true, Boolean(em));
    });
  });
});

I launch the mocha directly through the PowerShell console. The result:

enter image description here

like image 645
Andrey Bushman Avatar asked Sep 29 '17 10:09

Andrey Bushman


People also ask

Is it possible to use ES6 modules instead of the Nodejs modules system?

ES6 doesn't allow this, but there is an API in development for that. Since ES6 modules are part of the standard, I would use them.

Can I use ES6 imports?

Importing can be done in various ways:Node js doesn't support ES6 import directly. If we try to use import for importing modules directly in node js it will throw out the error.

What is CommonJS vs ES modules?

ES modules are the standard for JavaScript, while CommonJS is the default in Node. js. The ES module format was created to standardize the JavaScript module system. It has become the standard format for encapsulating JavaScript code for reuse.


2 Answers

Mocha has support for ESM from version 7.1.0 onward (release: Feb. 26, 2020).

This requires Node 12.11.0 or higher, and is subject to the current restrictions/limitations of using modules in Node:

  • Either you must use .mjs file extensions for source files that use ES modules, or you must have "type": "module" in your package.json
  • You can't use named imports when importing from CommonJS modules
  • Local import statements have to explicitly include the .js file extension

And so on.

Updated answer

I had previously recommended using the esm package as an alternative to Mocha's built-in module support, but it is no longer being mantained, can't handle newer syntactical constructs like ?., and seems to possibly not work at all with newer versions of Mocha.

However, @babel/register seems to work well for this:

mocha -r @babel/register -r regenerator-runtime/runtime

I'm using this with this preset (in .babelrc):

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

This setup requires the following packages:

  • @babel/core
  • @babel/register
  • @babel/preset-env
  • regenerator-runtime

You can also specify these in your .mocharc.js file instead of on the command line:

module.exports = {
    require: [
        '@babel/register',
        'regenerator-runtime/runtime',
    ],
};

My personal experience as of yet is that trying to take advantage of Mocha's new, inherent ESM support is still a considerable burden, but using this approach is quite seamless.

Previous answer

Another option is to use the esm package, which is not subject to the above limitations:

mocha -r esm

My personal experience as of yet is that trying to take advantage of Mocha's new, inherent ESM support is still a considerable burden, but using the esm package is quite seamless.

like image 152
JLRishe Avatar answered Oct 21 '22 08:10

JLRishe


In my case run with:

basic comand:

npx mocha --require esm test_path/

package.json

"scripts": {
    // ...
    "test": "npx mocha --require esm --reporter spec test_path/"
}

Runing

npm test
like image 25
fitorec Avatar answered Oct 21 '22 08:10

fitorec