Adam Terlson
Adam Terlson

Reputation: 12730

Bootstrapping a Mocha test suite

I have numerous tests spread across multiple files in a Node JS application. I'd like to run bootstrap code prior to Mocha's execution of any of the test files. This is so that I can, for example, set globals to be used in each of the actual tests.

Sample bootstrap code

global.chai = require('chai');
global.expect = chai.expect;
global.sinon = require('sinon');

It seems Mocha loads all files under /test alphabetically, so if I name this bootstrap code "bootstrap.js" and everything else with a starting letter after "B" it "works".

Obviously this is fragile and sucky, but I don't want to put this boilerplate requiring of my supporting libraries at the top of every test file.

How do I tell Mocha to load a bootstrap script first, or create something functionally equivalent?

Upvotes: 11

Views: 6919

Answers (4)

freedom
freedom

Reputation: 100

describe('异步钩子测试', function () {

  const lover = {
    bodyname: 'yueyue',
    girlname: 'fangfang'
  }

  const test = 'lihang'

  beforeEach('每一个测试之前的钩子', function () {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('通过')
      })
    })
  })

  it('方方爱张越', function () {
    // 是否等于yueuyue
    expect(lover.bodyname).to.equal('yueyue')

    // 是否是一个字符串
    lover.girlname.should.equal('fangfang')
  })
})

Upvotes: -2

Luke Schoen
Luke Schoen

Reputation: 4513

If prior to running Mocha you want to first run some bootstrap code in a file that uses ECMAScript 2015 Module syntax (i.e. import instead of require)

  • Create the following files:

./setupBabel.js (to bootstrap Babel transpiler)

require('babel-polyfill');
require('babel-register');

./setupDependencies.js (to bootstrap Chai and Sinon using ES2015 syntax)

import chai from 'chai';
import sinon from 'sinon';
global.expect = chai.expect;
global.sinon = sinon;

./test/codeSpec.js (example Unit Test using Chai, Sinon Stubs, Spies, and ES2015 syntax such as arrow functions, let, and const)

describe('test suite', () => {
  it('does not modify immutable constant value', () => {
    const myStub = sinon.stub();
    const mySpy = sinon.spy(myStub);
    myStub.returns({});
    let val = 1;
    expect(val).to.not.equal(2);
    sinon.assert.notCalled(mySpy);
  });
});
  • Run the following in terminal to install relevant NPM packages:

npm install babel-polyfill babel-register chai sinon mocha

  • Run the test suite with the following terminal command and flags:

mocha --require ./setupBabel.js --require ./setupDependencies.js ./test/codeSpec.js

Upvotes: 0

Yuriy Ivanov
Yuriy Ivanov

Reputation: 31

I use mocha's flag --delay

If you need to perform asynchronous operations before any of your suites are run, you may delay the root suite. Simply run Mocha with the --delay flag. This will provide a special function, run(), in the global context.

setTimeout(function() {
    // do some setup

    describe('my suite', function() {
        // ...
    });

    run();
}, 5000);

Upvotes: 3

Gntem
Gntem

Reputation: 7155

have you tried mocha --require mymodule.js TESTS_DIR

from the documentation

-r, --require

The --require option is useful for libraries such as should.js, so you may simply --require should instead of manually invoking require('should') within each test file. Note that this works well for should as it augments Object.prototype, however if you wish to access a module's exports you will have to require them, for example var should = require('should').

you could also write at the top of each test to load the require("./bootstrap.js") and run tests.

Upvotes: 12

Related Questions