Tape: Validate Error message & type with throws()

Created on 13 Jan 2016  路  10Comments  路  Source: substack/tape

Is there a way to validate an Error message with throws()? I am able to verify that the Error is caught, but there doesn't seem to be a way to compare the Error message to an expected message. Here's what I have so far:

var test = require('tape');

test('Pass invalid params to functon', function(assert){
    assert.throws(function() { 
        new ExampleObject(undefined, "validParam"); }, TypeError, "Should throw TypeError");
});

Thanks!

Most helpful comment

Tape is not here to be convenient.

would you mind putting this into the readme? That would have saved me time.

All 10 comments

I think I've found a partial solution, but I've run into another issue.

If I pass in the expected message using regex, it validates the message. However, what if I want to validate the message AND error type?

This works for checking the message:

test('Pass invalid params to functon', function(assert){
    assert.throws(function() { 
        new ExampleObject(undefined, "validParam"); }, /Fail - this is the expected error message/, "Should throw TypeError");
});

Now checking the error type seems to return true for _any_ error message, rather than the actual expected one.
Example:

test('Pass invalid params to functon', function(assert){
    assert.throws(function() { 
        new ExampleObject(undefined, "validParam"); },new TypeError( "Not what is expected but still passes"), "Should throw TypeError");
});

I've tried wrapping the TypeError as a String as well, but that doesn't help:

String(new TypeError("Not what is expected but still passes"))

based off of https://github.com/substack/tape/pull/181

I think I'd assume you should be able to pass in new TypeError("Not what is expected but still passes") and have it check both the type and the message (in place of just TypeError).

@ljharb I've tried that, but the test passes.

test('Pass invalid params to functon', function(assert){
    assert.throws(function() { 
        new ExampleObject(undefined, "validParam"); },new TypeError( "Not what is expected but still passes"), "Should throw TypeError");
});

right, sorry - what i mean is, i think the optimal behavior is that your above test fails, but would pass with the correct message.

@ljharb Yes, how would I go about achieving that? I'm having some trouble; the test is passing for any message I pass, not only the correct one.

Just write a helper function

test('thing', function t() {
  var err = tryCatch(function () { ... });
  assert.ok(err);
  assert.equal(err.message, 'wat');
  assert.equal(err.constructor.name, 'wat');
});

imo, that particular behavior should be what t.throws _does_ when given an error instance (as opposed to a constructor function)

@ljharb that diverges from upstream assert in node core.

Tape is not here to be convenient. It's here to output TAP.

Tape is not here to be convenient.

would you mind putting this into the readme? That would have saved me time.

I was struggling with this too. would be _convenient_ to have isError(). I want to assert that I did get the correct error message without wrapping a function in throws. Here is what I got to work...

  const res = await request(url)
    .set(jsonHeaders)
    .on('error', (err) => {
      const { message } = err.response.body;
      t.equal(message, 'My exact error message');
    }).catch(err => {
      t.pass('got an error response');
      t.end();
    })

_note; this uses superagent for the async call and tape-async library for async wrapping, but the same should be possible with some modifications _

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vasiliicuhar picture vasiliicuhar  路  7Comments

kl0tl picture kl0tl  路  7Comments

jimkang picture jimkang  路  3Comments

frankandrobot picture frankandrobot  路  4Comments

t3hmrman picture t3hmrman  路  7Comments