khalid13
khalid13

Reputation: 2837

Mocha/Chai async tests 'done()' fn not working

I'm testing a bank model I have as follows:

describe('Bank Model - Ajax', function () {

    it('loads bank', function (done) {

        var bank = new Bank();

        bank.OnLoaded = _(function () {
            expect(this.id).to.eql(1171);
            expect(true).to.eql(false);
            done();
        }).bind(bank);

        bank.load(1171);


    });
});

The load call makes an ajax request to my server. My problem is that expect(true).to.eql(false); throws an Uncaught Assertion Error and I'm not sure why. I'm using the recommended Mocha strategy of ending my test case with a done. Am I doing it wrong?

Thanks.

Upvotes: 12

Views: 5584

Answers (1)

Nick H
Nick H

Reputation: 11535

You're not doing anything wrong. Mocha isn't easily able to catch exceptions that are thrown within a callback since they execute after the test function has finished, so any failed assertions are uncaught fatal errors instead of nice diffs that you normally get with synchronous code.

People are working on workarounds such as providing a custom method that assertion libraries can call instead of throwing, or using Node Domains when running in Node. But for now it seems that it is still not behaving ideally.

Since the done method accepts a single parameter containing an error, you can add code to your test to catch exceptions within the callback and pass them to done(err) inside the catch block. But it'd get pretty messy fast.

Could reduce repetition with some sort of helper function like the below:

function catching(done, fn) {
  try {
    fn();
    done();
  } catch(err) {
    done(err);
  }
}

And then:

bank.OnLoaded = catching(done, _(function () {
  expect(this.id).to.eql(1171);
  expect(true).to.eql(false);
}).bind(bank));

Upvotes: 9

Related Questions