我正在尝试为 茉莉测试框架 期望发生错误。目前我正在使用 gitHub的茉莉花节点。.

在我的节点模块中,我有以下代码:

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() 还有其他一些变体,只是不知道如何使其起作用。

有帮助吗?

解决方案

您应该将功能传递到 expect(...) 称呼。您在这里拥有的代码:

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

正在尝试实际 称呼 parser.parse(raw) 试图将结果传递到 expect(...),

尝试使用匿名功能:

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

其他提示

您正在使用:

expect(fn).toThrow(e)

但是,如果您要查看函数注释(预期是字符串):

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-匿名函数):

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 {
   name: "Error",
   message: "Parsing is not possible"
}

我用以下内容替换茉莉花的Tothrow Matcher,这使您可以在异常的名称属性或其消息属性上进行匹配。对我来说,这使得测试更容易编写和脆弱,因为我可以做以下操作:

throw {
   name: "NoActionProvided",
   message: "Please specify an 'action' property when configuring the action map."
}

然后用以下测试:

expect (function () {
   .. do something
}).toThrow ("NoActionProvided");

这使我可以在不打破测试的情况下调整异常消息,而重要的是它抛出了预期的异常类型。

这是允许这样做的替代者:

jasmine.Matchers.prototype.toThrow = function(expected) {
  var result = false;
  var exception;
  if (typeof this.actual != 'function') {
    throw new Error('Actual is not a function');
  }
  try {
    this.actual();
  } catch (e) {
    exception = e;
  }
  if (exception) {
      result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected) || this.env.equals_(exception.name, expected));
  }

  var not = this.isNot ? "not " : "";

  this.message = function() {
    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
      return ["Expected function " + not + "to throw", expected ? expected.name || expected.message || expected : " an exception", ", but it threw", exception.name || exception.message || exception].join(' ');
    } else {
      return "Expected function to throw an exception.";
    }
  };

  return result;
};

一个比创建唯一目的的匿名函数更优雅的解决方案是包装另一个,是使用ES5的 bind 功能。绑定函数会创建一个新函数,当调用时, this 关键字设置为提供的值,并在调用新函数时提供的任何参数序列。

代替:

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

考虑:

expect(parser.parse.bind(parser, raw, config)).toThrow("Parsing is not possible");

绑定语法允许您使用不同的 this 价值观,在我看来,测试更具可读性。也可以看看: https://stackoverflow.com/a/13233194/1248889

如前所述,需要传递一个函数 toThrow 因为这是您在测试中描述的功能:“我希望此功能抛出X”

expect(() => parser.parse(raw))
  .toThrow(new Error('Parsing is not possible'));

如果使用 茉莉花匹配者 您还可以在适合情况时使用以下内容之一;

// I just want to know that an error was
// thrown and nothing more about it
expect(() => parser.parse(raw))
  .toThrowAnyError();

或者

// I just want to know that an error of 
// a given type was thrown and nothing more
expect(() => parser.parse(raw))
  .toThrowErrorOfType(TypeError);

我知道这是更多的代码,但您也可以做:

try
   do something
   @fail Error("should send a Exception")
 catch e
   expect(e.name).toBe "BLA_ERROR"
   expect(e.message).toBe 'Message'

对于咖啡馆爱好者

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

对于可能仍然面临此问题的任何人,对我而言,已发布的解决方案不起作用,并且一直在丢弃此错误: Error: Expected function to throw an exception.我后来意识到我期望引发错误的功能是一个异步功能,并期望承诺被拒绝,然后抛出错误,这就是我在代码中所做的:

throw new Error('REQUEST ID NOT FOUND');

那就是我在测试中所做的,它起作用了:

it('Test should throw error if request not found', willResolve(() => {
         const promise = service.getRequestStatus('request-id');
                return expectToReject(promise).then((err) => {
                    expect(err.message).toEqual('REQUEST NOT FOUND');
                });
            }));
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top