16

I am trying to test that my constructor will throw an error using the Teaspoon gem for Rails, with ChaiJS as my assertion library.

When I run the following test:

  it('does not create the seat if x < 0', function() {
    var badConstructor = function() {
      return new Seat({ radius: 10, x: -0.1, y: 0.2, seat_number: 20, table_number: 30});
    };

    expect(badConstructor).to.throw(Error, 'Invalid location');
  });

I get this output:

Failures:

  1) Seat does not create the seat if x < 0
     Failure/Error: undefined is not a constructor (evaluating 'expect(badConstructor).to.throw(Error(), 'Invalid location')')

The constructor is throwing the error, but I think I am not writing the test properly.

When I try running expect(badConstructor()) then I get the output:

Failures:

  1) Seat does not create the seat if x < 0
     Failure/Error: Invalid location
ThomYorkkke
  • 2,061
  • 3
  • 18
  • 26
  • Is it meant to be `expect(badConstructor())`? ie, you need to call the function. – Andy May 11 '15 at 19:31
  • I just tried it - to no avail. Now I get another error output - I added it in the OP. – ThomYorkkke May 11 '15 at 19:33
  • So it sounds like it''s working properly since "invalid location" is part of the error message. You either need to pick that up in your test, or add a `try/catch` statement in your function to return an error that you can test for. – Andy May 11 '15 at 19:36
  • But shouldn't expecting it to throw an error take care of me not needing the try/catch? – ThomYorkkke May 11 '15 at 19:36
  • Is it returning an Error tho or is it just logging something to the console? I'd bet on the latter. – Andy May 11 '15 at 19:39
  • I'm not sure what you mean. The test is failing though. – ThomYorkkke May 11 '15 at 19:41

3 Answers3

34

Had the same problem. Wrap your constructor with a function:

var fcn = function(){new badConstructor()};
expect(fcn).to.throw(Error, 'Invalid location');
David Vargas
  • 341
  • 2
  • 3
6

For test a throw message error inside a constructor, with mocha and chai you can write this test (with ES6 syntax):

'use strict';
// ES6 class definition
class A {
  constructor(msg) {
    if(!msg) throw new Error('Give me the message');
    this.message = msg;
  }
}

// test.js
describe('A constructor', function() {
  it('Should throw an error with "Give me the message" text if msg is null', function() {
    (() => new A()).should.throw(Error, /Give me the message/);
  });
});
See this Pen for check live working of above code zJppaj by Diego A. Zapata Häntsch (@diegoazh) on CodePen.
0

full example:

function fn(arg) {
  if (typeof arg !== 'string')
    throw TypeError('Must be an string')

  return { arg: arg }
}

it('#fn', function () {
  expect(fn).to.throw(TypeError)
  expect(fn.bind(2)).to.throw(TypeError)
  expect(fn('str')).to.be.equal('str')
})
Andre Figueiredo
  • 12,930
  • 8
  • 48
  • 74