谁还没个明天 2010-11-10 12:57 采纳率: 50%
浏览 283
已采纳

如何编写一个期望 Jasmine 出错的测试?

I'm trying to write a test for the Jasmine Test Framework which expects an error. At the moment I'm using a Jasmine Node.js integration from GitHub.

In my Node module I have the following code:

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

Now I try to write a test which expects this error:

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

I tried also Error() and some other variants and just can't figure out how to make it work.

转载于:https://stackoverflow.com/questions/4144686/how-to-write-a-test-which-expects-an-error-to-be-thrown-in-jasmine

  • 写回答

8条回答 默认 最新

  • YaoRaoLov 2010-11-10 13:13
    关注

    you should be passing a function into the expect(...) call. The code you have here:

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

    is trying to actually call parser.parse(raw) in an attempt to pass the result into expect(...),

    Try using an anonymous function instead:

    expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 零零乙 2010-11-10 13:06
    关注

    You are using:

    expect(fn).toThrow(e)
    

    But if you'll have a look on the function comment (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) {
    

    I suppose you should probably write it like this (using lambda - anonymous function):

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

    This is confirmed in the following example:

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

    Douglas Crockford strongly recommends this approach, instead of using "throw new Error()" (prototyping way):

    throw {
       name: "Error",
       message: "Parsing is not possible"
    }
    
    评论
  • ?yb? 2011-07-28 10:15
    关注

    I replace Jasmine's toThrow matcher with the following, which lets you match on the exception's name property or its message property. For me this makes tests easier to write and less brittle, as I can do the following:

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

    and then test with the following:

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

    This lets me tweak the exception message later without breaking tests, when the important thing is that it threw the expected type of exception.

    This is the replacement for toThrow that allows this:

    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;
    };
    
    评论
  • ℡Wang Yan 2014-02-15 17:41
    关注

    For coffeescript lovers

    expect( => someMethodCall(arg1, arg2)).toThrow()
    
    评论
  • 七度&光 2014-02-19 03:16
    关注

    I know that is more code but you can also do:

    try
       do something
       @fail Error("should send a Exception")
     catch e
       expect(e.name).toBe "BLA_ERROR"
       expect(e.message).toBe 'Message'
    
    评论
  • YaoRaoLov 2015-02-05 17:30
    关注

    A more elegant solution than creating an anonymous function who's sole purpose is to wrap another, is to use es5's bind function. The bind function creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

    Instead of:

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

    Consider:

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

    The bind syntax allows you to test functions with different this values, and in my opinion makes the test more readable. See also: https://stackoverflow.com/a/13233194/1248889

    评论
  • 旧行李 2017-01-24 08:51
    关注

    As mentioned previously, a function needs to be passed to toThrow as it is the function you're describing in your test: "I expect this function to throw x"

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

    If using Jasmine-Matchers you can also use one of the following when they suit the situation;

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

    or

    // I just want to know that an error of 
    // a given type was thrown and nothing more
    expect(() => parser.parse(raw))
      .toThrowErrorOfType(TypeError);
    
    评论
  • ?yb? 2018-02-15 11:09
    关注

    For anyone who still might be facing this issue, for me the posted solution didn't work and it kept on throwing this error: Error: Expected function to throw an exception. I later realised that the function which I was expecting to throw an error was an async function and was expecting promise to be rejected and then throw error and that's what I was doing in my code:

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

    and thats what I did in my test and it worked:

    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');
                    });
                }));
    
    评论
查看更多回答(7条)

报告相同问题?

悬赏问题

  • ¥20 C语言字符串不区分大小写字典排序相关问题
  • ¥15 关于#python#的问题:我希望通过逆向技术爬取1688搜索页下滑加载的数据
  • ¥15 学习C++过程中遇到的问题
  • ¥15 关于Linux的终端里,模拟实现一个带口令保护的屏保程序遇到的输入输出的问题!(语言-c语言)
  • ¥15 学习C++过程中遇到的问题
  • ¥15 请问,这个嵌入式Linux系统怎么分析,crc检验区域在哪
  • ¥15 二分类改为多分类问题
  • ¥15 Unity微信小游戏上调用ReadPixels()方法报错
  • ¥15 如何通过求后验分布求得样本中属于两种物种其中一种的概率?
  • ¥15 q从常量变成sin函数,怎么改写python代码?