Test for expected failure in Mocha

后端 未结 9 1967
终归单人心
终归单人心 2020-12-10 01:29

Using Mocha, I am attempting to test whether a constructor throws an error. I haven\'t been able to do this using the expect syntax, so I\'d like to do the following:

<
相关标签:
9条回答
  • 2020-12-10 02:26

    MarkJ's accepted answer is the way to go and way simpler than others here. Let me show example in real world:

    function fn(arg) {
      if (typeof arg !== 'string')
        throw TypeError('Must be an string')
    
      return { arg: arg }
    }
    
    describe('#fn', function () {
      it('empty arg throw error', function () {
        expect(function () {
          new fn()
        }).to.throw(TypeError)
      })
    
      it('non-string arg throw error', function () {
        expect(function () {
          new fn(2)
        }).to.throw(TypeError)
      })
    
      it('string arg return instance { arg: <arg> }', function () {
        expect(new fn('str').arg).to.be.equal('str')
      })
    })
    
    0 讨论(0)
  • 2020-12-10 02:32

    should.js

    Using the should.js library with should.fail

    var should = require('should')
    it('should fail', function(done) {
      try {
          new ErrorThrowingObject();
          // Force the test to fail since error wasn't thrown
           should.fail('no error was thrown when it should have been')
      }
      catch (error) {
       // Constructor threw Error, so test succeeded.
       done();
      }
    });
    

    Alternative you can use the should throwError

    (function(){
      throw new Error('failed to baz');
    }).should.throwError(/^fail.*/)
    

    Chai

    And with chai using the throw api

    var expect = require('chai').expect
    it('should fail', function(done) {
      function throwsWithNoArgs() {
         var args {} // optional arguments here
         new ErrorThrowingObject(args)
      }
      expect(throwsWithNoArgs).to.throw
      done()
    });
    
    0 讨论(0)
  • 2020-12-10 02:33

    Mocha in default is using Assert from node.js (https://nodejs.org/api/assert.html). You don't need any external libraries to check if a method throws an error.

    Assert has a method - assert.throws, it has three parameters, but only two really matters here:

    • function - here pass function, not function call
    • error - here pass or object constructor or function for checking the error

    Let's imagine that you have a function called sendMessage(message) which throws an error when message parameter is not set. Function code:

    function sendMessage(message) {
      if (!message || typeof message !== 'string') {
         throw new Error('Wrong message');
      }
      // rest of function
    }
    

    Ok, so in order to test it, you need additional function to cover input. Why? Because assert.throws doesn't give any opportunity to pass parameters to the function which going to be tested.

    So instead of

    // WRONG
    assert.throws(sendMessage, Error); // THIS IS WRONG! NO POSSIBILITY TO PASS ANYTHING
    

    you need to create anonymous function:

    // CORRECT
    assert.throws(() => {
      sendMessage(12);  // usage of wanted function with test parameters
    }, Error)
    

    Can you see the difference? Instead of passing function directly, I have put the function call inside anonymous function, in purpose of calling it with a prepared input.

    What about the second parameter. It depends from what kind of error should be thrown, in above example Error object was thrown, so I had to put there Error. In result of this action, assert.throws compares if thrown object is object of the same type. If instead of Error something different will be thrown, then this part needs to be changed. For example instead of Error I will throw a value of type String .

    function sendMessage(message) {
      if (!message || typeof message !== 'string') {
         throw 'Wrong message'; // change to String
      }
      // rest of function
    }
    

    Now the test call

    assert.throws(() => {
      sendMessage(12); // usage of wanted function with test parameters
    }, (err) => err === 'Wrong message')
    

    Instead of Error in second parameter I have used the comparison function in order to compare thrown error with the expectation.

    0 讨论(0)
提交回复
热议问题