Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocha 'this' in before and beforeEach hooks

The following test code, written using Mocha.js fails. I expect the someVal to be increased 3 times and equal 3 in the last test. The issue came up in more complex scenario where I used value set in outer before block to set up another in inner beforeEach block. Simplified case:

describe('increasing 3 times', function() {
  before(function() {
    this.instanceThis = this;
    return this.someVal = 0;
  });
  beforeEach(function() {
    return this.someVal += 1;
  });
  return describe('going deeper', function() {
    before(function() {
      return this.someVal += 1;
    });
    beforeEach(function() {
      return this.someVal += 1;
    });
    return it('has increased someVal to 3', function() {
      return this.someVal.should.equal(3);
    });
  });
});
like image 714
Madis Nõmme Avatar asked Dec 08 '14 12:12

Madis Nõmme


People also ask

What is beforeEach in Mocha?

Mocha has several hooks, including before, after, beforeEach, and afterEach. They make it possible to intercept tests before or after the test run and to perform specific tasks. For example, the beforeEach hook intercepts your test right before each test in a suite is run.

What are Mocha hooks?

Mocha is a feature-rich JavaScript test framework for Node. js. Mocha provides several built-in hooks that can be used to set up preconditions and clean up after your tests. The four most commonly used hooks are: before() , after() , beforeEach() , and afterEach() .

Which of these hooks runs before all tests in a describe block in Mocha JS?

According to MochaJS's documentation on hooks: before(function() {}) runs before all tests in the block. beforeEach(function() {}) runs before each test in the block. If you want to run a singular function at the start of your tests, use before() .

What is describe and it in Mocha?

The describe() function is a way to group tests in Mocha. You can nest your tests in groups as deep as you deem necessary. describe() takes two arguments, the name of the test group and a callback function.


1 Answers

this is not what you think it is. this gets redefined in every function() {} block (unless Mocha calls them in some specific way I'm not familiar with).

What you want is to use scope in your advantage:

describe('increasing 3 times', function() {
  var someVal; // Initialization.
  before(function() {
    someVal = 0; //No need to return from before()
  });
  beforeEach(function() {
    someVal += 1;
  });
  describe('going deeper', function() {
    before(function() {
      someVal += 1;
    });
    beforeEach(function() {
      someVal += 1;
    });
    return it('has increased someVal to 3', function() {
      someVal.should.equal(3);
    });
  });
});

Also, you don't need to return so much. In fact, you almost never have to return in test code.

like image 129
Madara's Ghost Avatar answered Sep 28 '22 04:09

Madara's Ghost