Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use setTimeout() functions within Mocha test cases?

I'm writing a test in Mocha / Node js and want to use a setTimeout to wait for a period before executing a block of code.

How can I accomplish this?

It appears that within a Mocha test case, setTimeout() does not work. (I am aware that you can setTimeout per test case and per test file, that's not what I need here.)

In a js file run with Node, ie, node miniTest.js, this will wait 3 seconds, then print the line inside the setTimeout function.

miniTest.js

console.log('waiting 3 seconds...');
setTimeout(function() {
    console.log('waiting over.');
}, 3000);

In a js file run with Mocha, ie, mocha smallTest.js, this will not wait, and will finish executing and exit without ever printing the line inside the setTimeout function.

smallTest.js:

mocha = require('mocha');

describe('small test', function() {
    it('tiny test case', function() {
        console.log('waiting 3 seconds...');
        setTimeout(function () {
            console.log('waiting over.')
        }, 3000);
    });
});
like image 859
nyarasha Avatar asked Sep 23 '15 02:09

nyarasha


People also ask

What is Mocha timeout?

By default Mocha will read a file named test/mocha.opts that can contain command line arguments. So you could create such a file that contains: --timeout 5000. Whenever you run Mocha at the command line, it will read this file and set a timeout of 5 seconds by default.

How is setTimeout implemented?

The setTimeout function sets a timer which executes a function on the next event cycle once the timer expires. This means, the final delay will depend on the current status of the event loop.


4 Answers

You are forgetting to pass parameter in it('tiny test case', function() and call done() after console.log in setTimeout method.

describe('small test', function(){
   it('tiny test case', function(done){
       console.log('waiting 3 seconds');
       setTimeout(function(){
           console.log('waiting over.');
           done();
       }, 3000)
   })
})
like image 55
Neelabh Singh Avatar answered Oct 27 '22 13:10

Neelabh Singh


You need to have done passed as a parameter in your test which will be invoked once the test passes.

You can write your test like

mocha = require('mocha');

describe('small test', function(done) {
    it('tiny test case', function() {
       console.log('waiting 3 seconds...');
       setTimeout(function () {
           console.log('waiting over.');
           done();
       }, 3000);
    });

});

This will wait 3 seconds after that it will print 'waiting over' and pass the test. You can also have a condition inside the timeout depending upon whether the condition is satisfied or not you can pass the test by calling

done();

or fail the test by either throwing an error or passing the error message in

done("Test Failed");
like image 28
Vipul Avatar answered Oct 27 '22 13:10

Vipul


Have your test function take a parameter (typically called done). Mocha will pass a function that you'll call in the setTimeout function (e.g. after console.log call done()).

See https://mochajs.org/#asynchronous-code.

like image 1
JMM Avatar answered Oct 27 '22 13:10

JMM


This is a complete example. You need to call done() in every assertion you make. You can leave out the before function and do the setTimeout in one of your it functions, but it should still use and call done() after assert.

var foo = 1;
before(function(done) {
  setTimeout(function(){
    foo = 2;
    done();
  }, 500)
});

describe("Async setup", function(done){

  it("should have foo equal to 2.", function(done){
    expect(foo).to.be.equal(2);
    done();
  });

  it("should have foo not equal 3.", function(done){
    expect(foo).to.be.not.equal(3);
    done();
  });

});
like image 1
Ska Avatar answered Oct 27 '22 11:10

Ska