Test for expected failure in Mocha

后端 未结 9 1945
终归单人心
终归单人心 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:07

    2017 answer if you need to do this with async code: using await and not needing any other libraries.

    it('Returns a correct error response when making a broken order', async function(){
      this.timeout(5 * 1000);
      var badOrder = {}
      try {
        var result = await foo.newOrder(badOrder)
        // The line will only be hit if no error is thrown above!
        throw new Error(`Expected an error and didn't get one!`)
      } catch(err) {
        var expected = `Missing required field`
        assert.equal(err.message, expected)
      }
    });
    

    Note the poster was only doing sync code, but I expect a lot of people using async were led here by the question title!

    0 讨论(0)
  • 2020-12-10 02:10

    With Chai throw (ES2016)

    http://chaijs.com/api/bdd/#method_throw

    For clarity... This works

    it('Should fail if ...', done => {
        let ret = () => {
            MyModule.myFunction(myArg);
        };
        expect(ret).to.throw();
        done();
    });
    

    This doesn't work

    it('Should fail if ...', done => {
        let ret = MyModule.myFunction(myArg);
        expect(ret).to.throw();
        done();
    });
    
    0 讨论(0)
  • 2020-12-10 02:13

    Chai now has

    should.fail() and expect.fail()

    https://github.com/chaijs/chai/releases/tag/2.1.0

    0 讨论(0)
  • 2020-12-10 02:17

    If you don't want to wrap a whole lot of source into the expect parameter, or if you have many arguments to pass and it just gets ugly, you can still do this with the original syntax just fine by leveraging the done argument that is provided (but was originally ignored):

    it('should throw exception when instantiated', function(done: Done) {
      try {
        new ErrorThrowingObject();
        done(new Error(`Force the test to fail since error wasn't thrown`));
      }
      catch (error) {
        // Constructor threw Error, so test succeeded.
        done();
      }
    }
    

    Because you're using done here, it allows you go execute arbitrary code above it in the try, then specify exactly where in your source you'd like to record the failure.

    Normally, someone may be tempted to throw or assert(false), but these will both be caught by the catch of the try, and cause you to do some meta-checking to determine if the error you caught was the expected error from your test, or if it was the final determination that your test failed. That's just a mess.

    0 讨论(0)
  • 2020-12-10 02:20

    You can try using Chai's throw construct. For example:

    expect(Constructor).to.throw(Error);
    
    0 讨论(0)
  • 2020-12-10 02:22

    If you are using should.js you can do (new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')

    If you don't want to should a separate library, you could also do something like this:

    it('should do whatever', function(done) {
        try {
            ...
        } catch(error) {
            done();
        }
    }
    

    This way, you know the error is caught if the test finishes. Otherwise, you will get a timeout error.

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