我正在尝试为Jasmine测试框架编写一个测试,该测试预计会出现错误。目前,我正在使用来自GitHub的Jasmine Node.js集成。

在我的Node.js模块中,我有以下代码:

throw new Error("Parsing is not possible");

现在我试着写一个测试,期望这个错误:

describe('my suite...', function() {
    [..]
    it('should not parse foo', function() {
    [..]
        expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
    });
});

我还尝试了Error()和其他一些变体,只是不知道如何使它工作。


当前回答

在我的例子中,抛出错误的函数是异步的,所以我遵循了这一点:

await expectAsync(asyncFunction()).toBeRejected();
await expectAsync(asyncFunction()).toBeRejectedWithError(...);

其他回答

对于CoffeeScript爱好者:

expect( => someMethodCall(arg1, arg2)).toThrow()

尝试使用匿名函数:

expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));

您应该向expect(…)调用传递一个函数。你的错误代码:

// incorrect:
expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));

实际上是试图调用parser.parse(raw),试图将结果传递给expect(…),

您正在使用:

expect(fn).toThrow(e)

但是如果你看一下函数注释(expected is string):

294 /**
295  * Matcher that checks that the expected exception was thrown by the actual.
296  *
297  * @param {String} expected
298  */
299 jasmine.Matchers.prototype.toThrow = function(expected) {

我想你应该这样写(使用lambda - anonymous函数):

expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");

下面的例子证实了这一点:

expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");

Douglas Crockford强烈推荐这种方法,而不是使用“throw new Error()”(原型):

throw {
   name: "Error",
   message: "Parsing is not possible"
}

一个比创建一个匿名函数(其唯一目的是包装另一个函数)更优雅的解决方案是使用ES5的bind函数。bind函数创建一个新函数,在调用该函数时,将其this关键字设置为所提供的值,并在调用新函数时所提供的任何参数之前设置给定的参数序列。

而不是:

Expect (function(){解析器。解析(原始配置);})。toThrow(“解析不可能”);

考虑:

期望(parser.parse。绑定(解析器,原始,配置))。toThrow(“解析不可能”);

绑定语法允许您测试具有不同this值的函数,在我看来,这使测试更具可读性。参见:

Jasmine的toThrow匹配器要求参数被包装在匿名函数中吗?

在我的例子中,抛出错误的函数是异步的,所以我遵循了这一点:

await expectAsync(asyncFunction()).toBeRejected();
await expectAsync(asyncFunction()).toBeRejectedWithError(...);