Mocha: Callback for timed out async call run for different test

Created on 6 Apr 2016  Â·  8Comments  Â·  Source: mochajs/mocha

Hi,

We are running mocha and need to wait for one test file to be done before the next one is run.

For example

  1. In the before hook for test file 1 we have a an asynchronous login ( using chaiHttp) and load test data.
  2. Before that file is done we log in using another test Fiile and make calls to the same db
  3. Now in the first test file the expected data is overwritten with data from the second test file .

A related stack overflow post is here:
http://stackoverflow.com/questions/26027890/running-two-different-test-files-sequentially-in-mocha

Thanks,
Deepak

needs-feedback stale unconfirmed-bug

Most helpful comment

Can you give an example of a spec with such a callback? I think the issue could be solved by either retuning the promise within the spec/hook, or only invoking the spec's callback when that async logic terminates.

E.g.

// You might have
it('test', function(done) {
  someAsyncCall();
  done();
});

// You should instead do
it('test', function(done) {
  someAsyncCall(function(err, res) {
    assert(!err);
    // other assertions
    done();
  });
});

All 8 comments

By default, mocha will run individual hooks/specs sequentially. If you need some logic to be ran sequentially, have you tried taking advantage of the before/after hooks?

Thanks. I see that the test files are run sequentially, but after a timeout is hit from an async call, mocha moves on to the next test and subsequent test files. When the async call from the first test returns (long after timeout period) its callback is executed for a different test (which happened to be in a different file).

Can you give an example of a spec with such a callback? I think the issue could be solved by either retuning the promise within the spec/hook, or only invoking the spec's callback when that async logic terminates.

E.g.

// You might have
it('test', function(done) {
  someAsyncCall();
  done();
});

// You should instead do
it('test', function(done) {
  someAsyncCall(function(err, res) {
    assert(!err);
    // other assertions
    done();
  });
});

Please see this:

test/mocha.opts
   --timeout 40000

tests/timeout.test.js
var chai = require('chai');
var expect = require('chai').expect;
var server = require('../server.js');
var chaiHttp = require('chai-http');
chai.use(chaiHttp);


var agent = chai.request.agent(server);

describe('Unit Tests',function(){

      it ("should timeout", function(done) {
            agent.get('/slowApi')
                    .end(function(err,res){
                         console.log("ABS - Response from slow api")
                            expect(res.body).to.have.property("slow_status");
                            done();
                    });

     });

});    


exports.slowApi = function(req, res) {
    setTimeout(function() {
        res.json({slow_status: true});
    }, 1000 * 100); 
};    

When running
mocha tests/timeout.test.js (tests/second test file)
there is a failure like so for a test in the second test file(that is slightly long):

Test File 2 
 Uncaught TypeError: Cannot read property 'body' of undefined
      at tests/timeout.test.js:17:36
      at Test.Request.callback (node_modules/chai-http/node_modules/superagent/lib/node/index.js:781:12)
      at ClientRequest.<anonymous> (node_modules/chai-http/node_modules/superagent/lib/node/index.js:736:10)
      at Socket.socketOnEnd (_http_client.js:331:9)
      at endReadableNT (_stream_readable.js:913:12)

We probably have a bigger problem, having a slow api in the first place.

@deepakmani I think I need to see more code. I can tell you that you need to check err in that callback for end().

This sounds somewhat similar to #2315, which was recently fixed

Setting aside multiple files and just focusing on multiple tests, is this an accurate demonstration of the issue?

(FWIW, on both Mocha 2.x and Mocha 3.x it outputs this for me:)

with done:
1) done(error) after timeout
√ this one is safe because error is reported through done

with promise:
2) reject after timeout
(node:14620) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: GOTCHA!
√ this one is safe because error is reported through promise

with throw:
3) throw after timeout
4) if the other test was not timing out, it would not interfere with this one

2 passing (2s)
4 failing

1) with done: done(error) after timeout:
Error: timeout of 10ms exceeded. Ensure the done() callback is being called in this test.

2) with promise: reject after timeout:
Error: timeout of 10ms exceeded. Ensure the done() callback is being called in this test.

3) with throw: throw after timeout:
Error: timeout of 10ms exceeded. Ensure the done() callback is being called in this test.

4) with throw: if the other test was not timing out, it would not interfere with this one:
Uncaught Error: GOTCHA!

Maybe I encounted the same problem. In my repo EVEModX/login-server@a5d2400c23f629ddd4bef451582b7cc13159f500 I got a timed out in accounts module 's before statements even though I called done(). And if I add a console.log() in async functions it would not timed out.

I am a bot that watches issues for inactivity.
This issue hasn't had any recent activity, and I'm labeling it stale. In 14 days, if there are no further comments or activity, I will close this issue.
Thanks for contributing to Mocha!

Was this page helpful?
0 / 5 - 0 ratings