carpiediem
carpiediem

Reputation: 2038

Mocha isn't displaying any details for failed tests

I'm migrating an app from Sails.js v0.12 to v1.0, which includes upgrading mocha from ^3.5.0 to ^5.2.0. I assume that is the root of the issue, but I can't seem to find a fix.

Before, when a test failed, there would be a summary of the error at the end of the mocha reporter output: the specific assertion that failed, file name, line number, error message, etc. Now, the reporter is coloring the it block in red, but no additional details are show.

I've tried changing the reporter in mocha.opts, which works for the actual execution output, but nothing is enabling the summary at the end. What am I missing?

// ./test/integration/models/User.test.js

describe('User', () => {

  describe('find()', () => {
    it('should return an array of users', () => {
      return User.find()
      .then((users) => {

        users.should.be.a('array');
        true.should.be.false;  // No problems if this is removed

      });
    });
  });

});

In the console:

> node ./node_modules/mocha/bin/mocha test/lifecycle.test.js test/integration/**/*.test.js


√ OtherModel method() should do something: 17ms
1) User find() should return an array of users
'Done.'
PS C:\repos\myproject>

Upvotes: 4

Views: 5657

Answers (3)

carpiediem
carpiediem

Reputation: 2038

Turns out that Mocha is fine and my test definitions are fine, I had simply fixed a totally different migration issue incorrectly. Since version 4, mocha will no longer automatically kill itself when it thinks all tests are complete. This means that one of these two options must be used:

  1. Add --exit to mocha.opts or to wherever the command is called
  2. Run process.exit() in your test suite's JavaScript

I tried the second option by adding process.exit() to the after() block in my test bootstrap file. This is a bad idea and resulted in the confusing behavior above.

To solve my issue, I removed my changes to the after() block and added --exit to mocha.opts. Thanks to Dhruv Choudhary for pointing me in the right direction.

Upvotes: 6

Dhruv Choudhary
Dhruv Choudhary

Reputation: 143

you can use done callback. The first strategy suggested in the mocha documentation is using the ‘done’ callback. This is an extra argument to the callback in the it . You call it after the last assertion in your test.

I have seen many people using done() method in wrong way. for example, look at below code,

describe('User', () => {

  describe('find()', () => {
    it('should return an array of users', (done) => {
      return User.find()
      .then((users) => {

        users.should.be.a('array');
        true.should.be.false;  // No problems if this is removed
        done();

      });
    });
  });

});

The above test will work fine and show the test passing, But calling done() in the same then callback is a bad idea because The above code works well until your expectation fails, you might get error like enter image description here

The above failure is not very useful . If we want to utilize the mocha’s error we shouldn’t call done() from the same then() callback. See the below test

describe('User', () => {

    describe('find()', () => {
        it('should return an array of users', (done) => {
            return User.find()
                .then((users) => {

                    users.should.be.a('array');
                    true.should.be.false;
                })
                .then(() => done(), done)
                .catch((error) => {
                    done(error);

                });
        });
    });
});

do not forget to wrap your error with catch block. Now see the difference in the mocha’s failure message with actual and expected..

Upvotes: 3

Tanmay Patil
Tanmay Patil

Reputation: 699

Please try adding done callback to your test case .

describe('User', () => {

  describe('find()', () => {
    it('should return an array of users', (done) => {
      return User.find()
      .then((users) => {

        users.should.be.a('array');
        true.should.be.false;  // No problems if this is removed
        done();

      });
    });
  });

});

Upvotes: 0

Related Questions