question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is there a way to run a piece of code when an assertion fails inside an end block?

See original GitHub issue

I find myself doing this in my tests:

chai.request(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })
  .end(function (err, res) {
     try {
       expect(err).to.be.null;
       expect(res).to.have.status(200);
     } catch (e) {
       //write err and res objects to custom log file
       throw e;
     }
  });

I add try and catch blocks around the chai assertion checking code so that I can log out the error and response objects to help me debug a test failure. Is there another way to do this? Thanks.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
keithamuscommented, Jul 22, 2016

we no longer have access to the err object anywhere

The error object is the e in the catch.

inside the catch, I don’t have access to the err and res objects to write to the logs

With chai http, the response object is attached to the error. A small exaple:

chai.request(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })
  .then((response) => {
    console.log('status is ', response.status);
  })
  .catch((error) => {
    console.log('status is ', error.response.status);
  })

inside the catch, despite us calling throw e, mocha no longer ends the test, rather it just times out. But if we call done() from within the catch, it results in a successful test outcome, which is not the outcome that we want to convey to mocha.

Yup, in Mocha you need to either return the promise, or call done. In my example:

it('returns 200 OK', (done) => {
  chai.request(app)
    .put('/user/me')
    .send({ password: '123', confirmPassword: '123' })
    .then((res) => {
      expect(res).to.have.status(200);
    })
    .then(done, done)
});

The .then is given done twice for good reason. If we expand this it might make more sense:

it('returns 200 OK', (done) => {
  chai.request(app)
    .put('/user/me')
    .send({ password: '123', confirmPassword: '123' })
    .then((res) => {
      expect(res).to.have.status(200);
      return undefined;
    })
    .then((result) => done(result /* undefined */), (error) => done(error /* Error */))
});

You can see that the first done is called with undefined and so Mocha considers that a test pass. The second done is called with error and Mocha sees this as a test fail. If you want do do stuff in the catch, you totally can but you always need to call done:

it('returns 200 OK', (done) => {
  chai.request(app)
    .put('/user/me')
    .send({ password: '123', confirmPassword: '123' })
    .then((res) => {
      expect(res).to.have.status(200);
    })
    .catch((error) => {
      //write err and res objects to custom log file
     throw error;
    })
    .then(done, done);
});

// or you can do this:

it('returns 200 OK', (done) => {
  chai.request(app)
    .put('/user/me')
    .send({ password: '123', confirmPassword: '123' })
    .then((res) => {
      expect(res).to.have.status(200);
      done();
    })
    .catch((error) => {
      //write err and res objects to custom log file
     done(error);
   });
});

mocha doesn’t log enough information about the error. When I do my custom error handing I use nodejs’ util.inspect(res) to log out the full res and err objects.

If mocha doesn’t log enough, you can always mix and match as you see fit. For example:

it('returns 200 OK', () => {
  return chai.request(app)
    .put('/user/me')
    .send({ password: '123', confirmPassword: '123' })
    .then((res) => {
      expect(res).to.have.status(200);
    })
    .catch((error) => {
      // write err and res objects to custom log file
      throw e;
    });
});

As long as you always throw the error, the Promise will reject and Mocha can work with it.


To summarise: with Promises you can add as many .then or .catch commands as you want. If you want the whole chain to fail, then make sure you rethrow errors in your catch.

0reactions
meebercommented, Oct 12, 2016

If you’re not working with promises or asynchronicity already like in the original poster’s example, then there’s no need to introduce them into the mix. Just use a try/catch block:

var differences = deep.diff(lhs, rhs)
try {
  expect(differences).to.equal(undefined)
} catch (err) {
  console.log(differences)
  throw err
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to continue execution after Assert.fail in catch block
If you want to continue your execution even after assertion failure, use soft assert instead of assert (Its called Hard Assert).
Read more >
Programming With Assertions - Oracle Help Center
This document shows you how to program with assertions. It covers the topics: Introduction; Putting Assertions Into Your Code; Compiling Files That Use...
Read more >
How to catch an assertion error in Java - Tutorialspoint
In order to catch the assertion error, we need to declare the assertion statement in the try block with the second expression being...
Read more >
Python's assert: Debug and Test Your Code Like a Pro
In this tutorial, you'll learn how to use Python's assert statement to document, debug, and test code in development. You'll learn how ......
Read more >
Assert Fail and continue question | Telerik Forums
Hi Cher, The only way for a coded step to be marked Fail is to allow the exception to happen and let Test...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found