【问题标题】:Node assert.throws not catching exception节点 assert.throws 未捕获异常
【发布时间】:2011-10-02 11:59:19
【问题描述】:

鉴于此代码:

var assert = require('assert');

function boom(){
    throw new Error('BOOM');
}

assert.throws( boom(), Error );

我得到这个输出,节点为 0.4.9:

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: BOOM
    at boom ([EDITED]/assert.throws.test.js:4:9)
    at Object.<anonymous> ([EDITED]/assert.throws.test.js:7:17)
    at Module._compile (module.js:402:26)
    at Object..js (module.js:408:10)
    at Module.load (module.js:334:31)
    at Function._load (module.js:293:12)
    at Array.<anonymous> (module.js:421:10)
    at EventEmitter._tickCallback (node.js:126:26)

对我来说,这意味着发生了未捕获的异常,而不是报告的已捕获异常。查看文档,我注意到示例看起来更像这样:

var assert = require('assert');

function boom(){
    throw new Error('BOOM');
}

assert.throws( boom, Error );

但是如何测试它是否在给定特定输入的情况下引发异常?例如:

var assert = require('assert');

function boom(blowup){
    if(blowup)
        throw new Error('BOOM');
}

assert.throws( boom, Error );

这将失败。我做错了什么,或者除了我之外每个人都知道什么秘密?

【问题讨论】:

    标签: unit-testing node.js


    【解决方案1】:

    示例采用一个函数,而您的示例代码调用一个函数并传递结果。异常发生在断言甚至可以查看它之前。

    将您的代码更改为:

    var assert = require('assert');
    
    function boom(){
        throw new Error('BOOM');
    }
    
    assert.throws( boom, Error ); // note no parentheses
    

    编辑:要传递参数,只需创建另一个函数。毕竟这是javascript!

    var assert = require('assert');
    
    function boom(blowup){
        if(blowup)
            throw new Error('BOOM');
    }
    
    assert.throws( function() { boom(true); }, Error );
    

    【讨论】:

    • 这是我的第二个示例演示的内容。这是有道理的,因为它需要在受控环境中调用测试函数。但是如果函数需要输入才能抛出异常,就像我的第三个示例一样?
    • 好吧,只要做 javascript 擅长的事情:创建新函数,就像我的编辑一样
    • 啊,我明白了。谢谢!
    • 非常感谢您提到附加参数的使用。这是一个很难找到的细节。可能不会尝试并寻找其他方法,所以再次感谢您。
    • 我在完全不同的区域(邮递员脚本)有完全相同的根本原因,所以感谢您让我发现它
    【解决方案2】:

    你可以使用bind():

    assert.throws( boom.bind(null), Error );
    

    带参数是:

    assert.throws( boom.bind(null, "This is a blowup"), Error );
    

    【讨论】:

      【解决方案3】:

      当前节点稳定版 (v4.1) 默认包含粗箭头功能支持(不需要 --harmony 标志),因此您可以执行以下操作:

      assert.throws(()=>boom(), Error);
      assert.throws(()=>boom(true), Error); // with params
      

      即使你在boom() 之后有括号(所以你实际上是在调用它,而不是传递对函数对象的引用),通过使用胖箭头函数你将它包装在一个块中,这就是assert.throws 期待。

      【讨论】:

        【解决方案4】:

        这与人们对其他断言 Mocha/Chai 的问题密切相关。有关node 示例的说明,请参见此答案:
        Mocha / Chai expect.to.throw not catching thrown errors

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-28
          • 2014-07-15
          • 1970-01-01
          • 1970-01-01
          • 2010-09-28
          • 2012-05-31
          相关资源
          最近更新 更多