【问题标题】:Catching thrown errors with SinonJS使用 SinonJS 捕获抛出的错误
【发布时间】:2015-12-29 20:15:31
【问题描述】:

我有一个可能会引发错误的方法,但是我在为这种情况编写一个 SinonJS/Mocha/Should 单元测试用例时遇到了麻烦。

正在测试的示例函数:

function testError(value) {
  if (!value) {
    throw new Error('No value');
    return false;
  }
};

样本测试:

describe('#testError', function() {
  it('throws an error', function() {
    var spy = sinon.spy(testError);
    testError(false);
    spy.threw().should.be.true();
  });
});

这个输出:

  #testError
    1) throws an error


  0 passing (11ms)
  1 failing

  1) #testError throws an error:
     Error: No value
      at testError (tests/unit/js/test-error.js:6:14)
      at Context.<anonymous> (tests/unit/js/test-error.js:14:6)

我原以为诗浓会捕捉到错误并允许我监视投掷,但它似乎反而未能通过测试。有什么想法吗?

我提到了Don't sinon.js spys catch errors?,但唯一的解决方案是使用expect。如果可能的话,我更愿意使用一个断言库。

【问题讨论】:

    标签: node.js unit-testing mocha.js sinon should.js


    【解决方案1】:

    这似乎在 try/catch 中有效:

    function foo() { throw new Error("hey!"); }
    var fooSpy = sinon.spy(foo);
    try {
      fooSpy();
    } catch (e) {
      // pass
    }
    assert(fooSpy.threw());
    

    请注意,您必须调用 fooSpy而不是 foo 本身。

    但也要注意.should.be.true() 不是Sinon 的一部分,所以您可能已经在使用Chai 或类似的库,在这种情况下expect(foo).to.have.thrown()assert.throws(foo, someError) 语法似乎很重要更好。

    更新:如果您使用的是 ShouldJS,看起来您可以使用 should.throws。我仍然认为这比使用 Sinon 版本更好。

    【讨论】:

    • 谢谢,@nrabinowitz。看起来should.throws 可能是票。请参阅下面的修改后的答案。
    【解决方案2】:

    修订

    遵循@nrabinowitz 的有用建议,这里有一个使用should.throws 的解决方案。这避免了完全使用Sinon.spy

    describe('#testError', function() {
      it('throws an error', function() {
        should.throws(function() {
          testError(false);
        });
      });
    });
    

    【讨论】:

    • 这和你想的不一样。 stub.throws() 是存根的预编程行为,而不是断言它已被调用。存根调用底层函数 - 用另一个不抛出的函数试试这个,你会看到行为没有改变。
    • 啊,你是对的。使用stub 是误报。我认为使用should.throws 并调用被测的实际函数是可行的。并且完全避免使用诗乃。请参阅我修改后的答案。
    【解决方案3】:
                const bootstrap = async anyParam => {
                    if(!anyParam){
                        throw new Error('test')
                    }
    
                    await anyParam()
                }
    
                const spy = sinon.spy(bootstrap)
    
                try {
                    await spy();
                } catch (e) {
                    expect(e.message).to.be.equal('test')
                    spy.called = false
                }
    
                expect(spy.called).to.be.equal(false);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2011-09-07
      • 2015-10-05
      • 1970-01-01
      • 2016-02-07
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多