Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test exceptions in lab?

Tags:

hapi.js

I'm writing test cases using lab and I would like to test whether or not an exception is thrown from my plugin. The problem is, hapi allows the exception to bubble up while also setting the response to internal server error 500 which causes my test to fail.

We can test for this response expect(res.statusCode).to.equal(500) but the test will still fail.

I can't use try/catch around server.inject because the exception is thrown asynchronously.

How do I use lab to test for exceptions?

like image 525
Kevin Wu Avatar asked Mar 12 '15 05:03

Kevin Wu


1 Answers

An error thrown inside a handler is caught by the domain on the request object. You can test for the presence of that a couple of different ways.

I'm not particularly happy with either of these ideas but they do both work. Hopefully someone else knows a better way.

The plugin

exports.register = function (server, options, next) {

    server.route({
        method: 'GET',
        path: '/',
        handler: function (request, reply) {

            throw new Error('You should test for this');

            reply();
        }
    });

    next();
}

The test

describe('Getting the homepage', function () {

  it('Throws an error', function (done) {

    server.inject({url: '/'}, function (resp) {

      var error = resp.request.response._error;

      expect(error).to.be.an.instanceof(Error);
      expect(error.message).to.equal('Uncaught error: You should test for this');
      done();

    });
  });
});

Alternative

If you don't like the idea of accessing the private _error property (as above), you can add a listener to the domain and store the error yourself on the request object.

server.ext('onPreHandler', function (request, reply) {

    request.domain.on('error', function (error) {
        request.caughtError = error;
    });

    reply.continue();
});

The test

describe('Getting the homepage', function () {

  it('Throws an error', function (done) {

    server.inject({url: '/'}, function (resp) {

      var error = resp.request.caughtError;

      expect(error).to.be.an.instanceof(Error);
      expect(error.message).to.equal('Uncaught error: You should test for this');
      done();

    });
  });
});
like image 97
Matt Harrison Avatar answered Jan 03 '23 15:01

Matt Harrison