Global `before` and `beforeEach` for mocha?

JavascriptUnit Testingmocha.js

Javascript Problem Overview


I'm using mocha for javascript unit-testing now.

I have several test files, each file has a before and beforeEach, but they are exactly the same.

How do I provide a global before and beforeEach for all of them (or some of them)?

Javascript Solutions


Solution 1 - Javascript

In the root of the test folder, create a global test helper test/helper.js which has your before and beforeEach

// globals
global.assert = require('assert');

// setup
before();
beforeEach();

// teardown
after();
afterEach();

Solution 2 - Javascript

from the mocha documentation… > ## ROOT-LEVEL HOOKS > > You may also pick any file and add “root”-level hooks. For example, > add beforeEach() outside of all describe() blocks. This will cause the > callback to beforeEach() to run before any test case, regardless of > the file it lives in (this is because Mocha has an implied describe() > block, called the “root suite

All regular describe()-suites are first collected and only then run, this kinda guarantees this being called first.

'use strict'
let run = false

beforeEach(function() {
	if ( run === true ) return
	console.log('GLOBAL ############################')
	run = true
});

Remove the run-flag, if you want to see it run each time, before every test.

I named this file test/_beforeAll.test.js. It has no need to be imported/required anywhere, but the .test. (resp. .spec.) in the filename is important, so that your testrunner picks it up…


bonus track 8-): using mocha.opts \o/

If there's stuff, you truly only want to set up once before running your tests (regardless which ones...), mocha.opts is a surprisingly elegant option! – Just add a require to your file (yes, even if it contributes little to mocha, but rather to your test setup). It will run reliably once before:

enter image description here

( in this example I detect, if a single test or many tests are about to run. In the former case I output every log.info(), while on a full run I reduce verbosity to error+warn... )

Update:

If someone knows a way, to access some basic properties of the mocha suite that is about to be run in once.js, I would love to know and add here. (i.e. my suiteMode-detection is lousy, if there was another way to detect, how many tests are to be run…)

Solution 3 - Javascript

Declare a before or beforeEach in a separate file (I use spec_helper.coffee) and require it.

spec_helper.coffee

afterEach (done) ->
  async.parallel [
    (cb) -> Listing.remove {}, cb
    (cb) -> Server.remove {}, cb
  ], ->
    done()

test_something.coffee

require './spec_helper'

Solution 4 - Javascript

I've had similar issue when I needed to "mock" global variables used by one of dependencies.

I used .mocharc.js for that, since code in that JS file is being executed once when "mocha" environment is being setup.

Example .mocharc.js:

global.usedVariable = "someDefinedValue";

/** other code to be executed when mocha env setup **/

module.exports = {};

This worked for me, nevertheless this looks quite "dirty" way to do that. Please, comment if you know a better place for that code :)

Solution 5 - Javascript

mochaHooks root hook plugin minimal example on Mocha 8

This mechanism is currently documented at: https://mochajs.org/#root-hook-plugins

It does not work for before, only for beforeEach however, since before is not in the list of available hooks from: https://mochajs.org/#available-root-hooks

Here's a demo:

test/global.js

// Root hook.
exports.mochaHooks = {
  beforeEach(done) {
    console.log('mochaHooks.beforeEach');
    done();
  },
};

// Bonus: global fixture, runs once before everything.
exports.mochaGlobalSetup = async function() {
  console.log('mochaGlobalSetup');
};

test/mytest.js

var assert = require('assert');

describe('describe0', function() {
  // Only runs before the current describe.
  before(async () => {
    console.error('before describe 0');
  });
  beforeEach(async () => {
    console.error('beforeEach describe 0');
  });
  it('it 0 0', function() {
    assert.equal(0, 0);
  });
  it('it 0 1', function() {
    assert.equal(0, 0);
  });

  describe('describe 0 0', function() {
    before(async () => {
      console.error('before describe 0 0');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 0');
    });
    it('it 0 0 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 0 1', function() {
      assert.equal(0, 0);
    });
  });

  describe('describe 0 1', function() {
    before(async () => {
      console.error('before describe 0 1');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 1');
    });
    it('it 0 1 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 1 1', function() {
      assert.equal(0, 0);
    });
  });
});

Then you enable that file with --require:

npx mocha --require test/global.js test/

Outcome:

mochaGlobalSetup


  describe0
before describe 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 1
    describe 0 0
before describe 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 1
    describe 0 1
before describe 0 1
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 1


  6 passing (6ms)

So we see that the global hook ran before every local beforeEach.

For before I couldn't find a better solution than defining a helper and calling it from every before: https://stackoverflow.com/questions/28191243/how-can-i-make-mocha-load-a-helper-js-file-that-defines-global-hooks-or-utilitie

Tested on mocha 8.3.2, Node v14.16.0.

Solution 6 - Javascript

The use of a modules can make it easier to have a global setup/teardown for your test suite. Here is an example using RequireJS (AMD modules):

First, let's define a test environment with our global setup/teardown:

// test-env.js

define('test-env', [], function() {
  // One can store globals, which will be available within the
  // whole test suite.
  var my_global = true;

  before(function() {
    // global setup
  });
  return after(function() {
    // global teardown
  });
});

In our JS runner (included in mocha's HTML runner, along the other libs and test files, as a <script type="text/javascript">…</script>, or better, as an external JS file):

require([
          // this is the important thing: require the test-env dependency first
          'test-env',

          // then, require the specs
          'some-test-file'
        ], function() {

  mocha.run();
});

some-test-file.js could be implemented like this:

// some-test-file.js

define(['unit-under-test'], function(UnitUnderTest) {
  return describe('Some unit under test', function() {
    before(function() {
      // locally "global" setup
    });

    beforeEach(function() {
    });

    afterEach(function() {
    });

    after(function() {
      // locally "global" teardown
    });

    it('exists', function() {
      // let's specify the unit under test
    });
  });
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFreewindView Question on Stackoverflow
Solution 1 - JavascriptAJcodezView Answer on Stackoverflow
Solution 2 - JavascriptFrank NockeView Answer on Stackoverflow
Solution 3 - JavascriptMichelle TilleyView Answer on Stackoverflow
Solution 4 - JavascriptAleksey MorozView Answer on Stackoverflow
Solution 5 - JavascriptCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 6 - JavascriptchikamichiView Answer on Stackoverflow