Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocha test suite never ends when setInterval(...) running

I have a suite of tests which contains code with a setInterval(...) call.

When running this code in mocha via a windows powershell command line, all tests will run, but the test runner will hang indefinitely afterwards.

The command I am using is mocha "./unitTests/**/*.js"

Is there a way to force the test runner to close?

Alternatively is there a way to determine that the code is running in a test environment so that I can disable my setInterval(...) calls?

Example code:

// MODULE TO TEST
setInterval(function(){
    // do cleanup task
}, 1000000);

function testFunction(){
    return "val";
}

export {
    testFunction
}

// TEST MODULE
describe("Test setInterval", function() {  
    it("should finish", function() {
        testFunction().should.be.equal("val");

        // This test will complete and all others, but the entire suite will not
    });
});
like image 603
Shane Avatar asked Jan 09 '18 16:01

Shane


People also ask

Do Mocha tests run sequentially?

js and in the browser. It's designed for testing both synchronous and asynchronous code with a very simple interface. Mocha runs tests serially to deliver flexible and accurate reporting while mapping uncaught exceptions to their corresponding test cases.

How do I change the default timeout on my Mocha?

Whenever you run Mocha at the command line, it will read this file and set a timeout of 5 seconds by default. Another way which may be better depending on your situation is to set it like this in a top level describe call in your test file: describe("something", function () { this. timeout(5000); // tests... });

Do Mocha tests run in parallel?

Mocha does not run individual tests in parallel. That means if you hand Mocha a single, lonely test file, it will spawn a single worker process, and that worker process will run the file. If you only have one test file, you'll be penalized for using parallel mode.


1 Answers

The root cause is that Mocha by default considers the suite to be "done" when Node considers that the process is "done". And by default Node waits for all uncleared timeouts and intervals to be "done" before calling the process "done". (An "uncleared" timeout or interval is one that has been created and never had clearTimeout/clearInterval called on it.)

A timeout is done when the callback you pass to setTimeout has finished executing, but an interval will never be done because by design it calls its callback forever and ever.

Your options are:

  1. Determine a condition by which the interval should be cleared, and clear it with clearInterval.

  2. Use unref on the return value of setInterval. This tells Node to ignore the interval when deciding whether the process is "done".

  3. Invoke mocha with the --exit option (introduced in Mocha 4), which forcibly exits the process when Mocha is done with the test suite.

I would use options 1 or 2. The third option works but if your test suite becomes more complex, it could hide problems you should be taking care of. I would not use it if there is a more focused solution that can be used.

like image 65
Louis Avatar answered Nov 15 '22 04:11

Louis