Mocha: BeforeEach inside Describe

Created on 8 Nov 2016  路  7Comments  路  Source: mochajs/mocha

I'm not sure if my case is actually a bug or if I'm not understanding correctly how to use beforeEach.

I have a common.js file with:

describe('API', function () {
  console.log("Common - Describe")
  beforeEach(async () => {
    console.log("Common - Before")
  })
})

Then in my test file I have:

require ('./common')

describe.only('API', function () {
  it('should do something', async () => {
    console.log("it")
  })
  // many more "it"s
})

I only get logs for "Common - Describe" and "it". The beforeEach never gets called.

Any ideas on what I'm doing wrong?

Most helpful comment

@boneskull no comment

All 7 comments

Mocha uses a stack data structure to register all API calls.

In order to achieve what you want, you have to do this instead:

// common.js
  beforeEach(async () => {
    console.log("Common - Before")
  })

require ('./common'); // requires the above code

describe.only('API', function () {
  it('should do something', async () => {
    console.log("it")
  })
  // many more "it"s
})

otherwise, the beforeEach won't get applied because the hook is not "at the right level of the stack".

The issue with that is that I have 3 different major "common.js" files for three different modules of my app. I can't have all three execute before each test. That's why I need to include the describe in the common.js.

I have a extensions module for common code, a worker module for the worker of my app and an api module for the rest api. Each has it's common.js for test setup.

I can't have the worker beforeEach happen in each of the tests of the API.

What was happening is that they were accumulating: the API only ran the API common. The extensions ran both the API and extensions. The worker ran all three before each test.

Yep, this is why Mocha has problems IMO, unless you know what you are doing, it's hard to know what to do :) Let me try to solve your issue though. This _will_ work for you.

describe(1, function(){

    require('beforeEach1');   // if you load it here, then the beforeEach will only apply to registered calls inside this describe block

   // do your thing;
    describe(x, function(){

    });

})


describe(2, function(){

    require('beforeEach2');   // ditto above

     // do your thing;
    describe(y, function(){

    });
})


describe(3, function(){

    require('beforeEach3');  // ditto above

  // do your thing;
    describe(z, function(){

    });
})

that should solve your problem. Also considering wrapping your shared code in functions so that you don't accidentally load a file you didn't mean to load. Only if you explicitly call the file.

So maybe do this:

//shared.js / common.js

module.exports = {


   one: function() {

        beforeEach(1, function(){

        })

   },

  two: function() {

        beforeEach(2, function(){

        })

   },

  three: function() {

        beforeEach(3, function(){

        })

   }
};

of course now it's possible to call those functions more than once by accident, whereas if they were just in a module, modules only run/load once and then are cached.

Thanks! That was very helpful!

no problem amigo

@ORESoftware Thanks for helping @heynemann.

While this is appreciated, what _isn't_ appreciated is your history of unproductive commentary on Mocha and its authors / maintainers. Constructive criticism is welcome, but your criticism is seldom of this variety.

It's becoming a distraction to not just me, but other maintainers. You will be banned from the mochajs org (and this issue tracker) if we see more of it. Thanks!

@boneskull no comment

Was this page helpful?
0 / 5 - 0 ratings

Related issues

robertherber picture robertherber  路  3Comments

seelikes picture seelikes  路  3Comments

enigmatic00 picture enigmatic00  路  3Comments

CADBOT picture CADBOT  路  3Comments

smithamax picture smithamax  路  4Comments