Mocha: done() not working inside promise

Created on 26 Jul 2014  路  8Comments  路  Source: mochajs/mocha

I use mocha and chai to test my AngularJS frontend. My problem is that done does`nt seem to end the test and gives me a timeout error.

it 'should save test if channel exists', (done) - > test = {
    title: 'found'
    keywords: []
}
$httpBackend.when 'GET', url + test.title.respond {
    "pageInfo": {
        "totalResults": 1,
            "resultsPerPage": 5
    },
        "items": [{
        "id": "id_found",
            "snippet": {
            "title": "Found",
                "thumbnails": {
                "default": {
                    "url": "http://example.com/thumbnail.png"
                }
            }
        }
    }]
}
factory.add test.then(r) - > expect(r.ok).to.equal true
expect(r.id).to.equal 'id_found'
done()
    .
catch (err) -> done err
$httpBackend.flush()

Most helpful comment

what language am I even reading here

All 8 comments

what language am I even reading here

+1, here's a simpler example

describe("A promise", function() {
    it.only('eventually calls done', function(done) {
        return new Promise(function(resolve) {       
            resolve('resolved');                     
        }).then(function(result) {                   
            assert(false);                           
            done();                                  
        });                                          
    });                                              
});                                                  

screenshot from 2014-07-26 20 03 47

there's no reason to use done here

describe("A promise", function() {
    it.only('eventually calls done', function() {
      return new Promise(function(resolve) {
        resolve('resolve');
      }).then(function(){
        assert(false);
      });
    });
});
  A promise
    1) eventually calls done


  0 passing (13ms)
  1 failing

  1) A promise eventually calls done:
     AssertionError: false == true
      at /Users/tj/dev/mocha-test-2/test.js:8:9

What about the case where I can't actually return the promise?

function asyncFunc(callback) {                        
    new Promise(function(resolve) {                   
        resolve('resolved');                          
    }).then(callback);                            
}                                                     

describe("A callback from a promise", function() {                    
    it.only('eventually calls done', function(done) { 
        asyncFunc(function() {                        
            assert(false);                            
            done();                                   
        });                                           
    });                                               
});                                                                                                   
function (done) {
  new Promise( resolve => resolve('resolved') )
  .then(function (res) {
    assert(res)
    done()
  }, done)
}

taht should work. you're missing the second done in .then(). and don't return a promise if you want to use done

I'm having the same issue using mochajs and chai.expect. And I tried both approaches mentioned here.

@travisjeffery's approach:

it ("Test", function(done) {
    return Promise.resolve()
    .then(function() {
        expect(1).to.equal(2);
    });
});

@jonathanong's approach:

it ("Test", function(done) {
    Promise.resolve()
    .then(function() {
        expect(1).to.equal(2);
        done();
    }, done);
});

I'm getting the exact same error mentioned here for both approaches:

screen shot 2017-03-29 at 7 08 35 pm

Any ideas?

If you're using the current version of Mocha, the first one should give you a different error about not being allowed to both return a promise and use done (there were cases where we could not detect mistakes with both used in combination and the previous behavior when both were used was never correct anyway [it ignored one of them, I forget which]). Changing (done) to () should fix it.

If that does not work, the second one should work if , done); is changed to ).catch(done); -- the second handler passed to then does not handle exceptions thrown by the first handler passed to then.

@ScottFreeCode Great! Thanks, I tried both approaches you suggested and they both work. However, the first approach - before applying your fix - did indeed return a timeout error rather than the "not being allowed to return a promise and use done" error. For the record, I'm using gulp-mocha. So, not sure if this would handle things differently.

Thanks again for the quick reply :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

luoxi001713 picture luoxi001713  路  3Comments

jamietre picture jamietre  路  3Comments

3p3r picture 3p3r  路  3Comments

Swivelgames picture Swivelgames  路  3Comments

seelikes picture seelikes  路  3Comments