w3resource

Synchronous code, arrow functions and hooks


Today we will discuss what happens when we test synchronous codes, arrow functions as well as testing for hooks.

Synchronous code

A synchronous code is a code that runs one at a time, that means one line of code will be executed at a time in the order that the codes appear.

Whenever you are testing a synchronous code, you should omit the callback and Mocha will know that it should automatically continue on to the next test.

Here is an example to illustrate synchronous code testing in Mocha:

describe('Array', function() {
  describe('#indexOf()', function() {
    it('has to return -1 when the value is not present', function() {
      [1, 2, 3].indexOf(5).should.equal(-1);
      [1, 2, 3].indexOf(0).should.equal(-1);
    });
  });
});

Arrow functions

Passing arrow functions (aka lamda) to Mocha is not encouraged. this will be lexically bound by Lambdas and will not be able to access the Mocha context. For instance, the code below will fail:

describe('my suite', () => {
  it('my test', () => {
    // has to set the timeout of this test to 1000 ms; instead will fail
    this.timeout(1000);
    assert.ok(true);
  });
});
mocha arrow functions

In the case where you don't want to use Mocha?s context, then lamdas should work. However, this result is more difficult to refactor if the need eventually arises.

Hooks

Mocha provides these hooks: before(), after(), beforeEach(), and afterEach() with its default BDD ?style interface. These has to be used to set up preconditions and clean up after your tests.

describe('hooks', function() {
  before(function() {
    // will run before all tests in this block
  });

  after(function() {
    // will run after all tests in this block
  });

  beforeEach(function() {
    // will run before each test in this block
  });

  afterEach(function() {
    // will run after each test in this block
  });```

  // test cases
});

Describing hooks

You can invoke any hook with an optional description, this makes it easier to pinpoint errors in your tests. If you give a hook a named function, that name is used if no description is supplied.

beforeEach(function() {
  // beforeEach hook
});

beforeEach(function namedFun() {
  // beforeEach:namedFun
});

beforeEach('some description', function() {
  // beforeEach:some description
});

Asynchronous hooks

All hooks (before(), after(), beforeEach(), afterEach()) can be sync or async as well, they behave much like a regular test-case. For instance, you may want to populate database with dummy content before each test:

describe('Connection', function() {
  var db = new Connection(),
    tobi = new User('tobi'),
    loki = new User('loki'),
    jane = new User('jane');

  beforeEach(function(done) {
    db.clear(function(err) {
      if (err) return done(err);
      db.save([tobi, loki, jane], done);
    });
  });

  describe('#find()', function() {
    it('responds with matching records', function(done) {
      db.find({type: 'User'}, function(err, res) {
        if (err) return done(err);
        res.should.have.length(3);
        done();
      });
    });
  });
});

Root-level hooks

You can also pick any file and add root-level hooks to it. For instance, add beforeEach() outside of all describe() blocks. This causes the callback to beforeEach to run before any test case, irrespective of the files that it lives in.

beforeEach(function() {
  console.log('this is before every test in every file');
});


Inviting useful, relevant, well-written and unique guest posts