4

2013 年 7 月 2 日更新

使用包装匿名函数的最后一种方法可能会引入一些奇怪的测试行为。如果您预计会抛出错误,但实际执行中有错误,则测试将通过,但会传递任何错误,并且可能不是您期望的错误。我做了两件事,如果我指定它是一个错误,我确保从存根返回的错误文本和抛出的错误是相同的。如果它来自我不一定知道错误的第三方库,我会输入一些任意值,以便我知道通过特定于我正在测试的单元。使用 sinon.js 存根的示例。

    it('should return an error if the save fails', function(){
        stubCall.restore();
        stubCall = sinon.stub(Provider, 'save').callsArgWith(1, new Error('Save Error'));

        (function(){
            User.create(fakeUser, function(err, user){
               if(err)
                throw err;
            });
        }).should.throw("Save Error");
    });

我正在进入 Node.js 并尝试使用 Mocha 和 should.js(以及在某些时候的 sinon)做一些行为驱动开发(BDD)。

我遇到的一件事是测试回调返回的错误,例如这个简单的测试:

it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {}; 

        Provider.execute(stubQuery, function (err) {
            //should.not.exist(err);
            should.have.property('message', 'Invalid Query Object');
        });
    });

具有以下功能:

PostgresqlProvider.prototype.execute = function (query, cb) {

};

我尝试和测试什么都没关系,测试总是通过(should.exist 等),我可以让它首先失败的唯一方法是添加 cb(null); 进入执行功能,这有点违背我正在做的事情,因为我试图在添加行为之前进行测试,而不是添加行为以使测试失败。

我知道我在这里犯了一些真正的新手错误,可能在几个级别上,但我没有掌握对作为回调传递的错误的测试没有抛出(我相信我可以更轻松地测试)!

更新

Using the code from Herman, i adjusted and that indeed words (the test is failing with no behavior defined)

        it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {};
        Provider.execute(stubQuery, function (err) {
            if (err) throw new Error(err);
        }).should.throw();
    });

issue now is i can't "catch" the error if sent in the callback to pass the test, the should.throw method doesn't get called, it just states that expected a throw to happen but didnt even though i am returning an error to the callback from my method. This could be down to scope but i am unsure if i should add some form of closure, and at what level.

UPDATE 2

Figured it out, i needed to wrap the call to the function inside a closure, not the callback (Doh!) and then place the assert (should.throw) at the end of the closure;

        it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {};
        (function(){
            Provider.execute(stubQuery, function (err) {     
                if (err) 
                    throw err;
            });
         }).should.throw();
    });
4

1 回答 1

0

You need to generate an exception inside your test function for the test to fail.

I'd add if (err) throw "Invalid query error " + err this way:

it('should return an error if you try and execute an invalid Query object', function () {
    var stubQuery = {}; 

    Provider.execute(stubQuery, function (err) {
        if (err) throw "Invalid query error " + err
    });
});

That should do.

(ON UPDATE)

should.throw()对我也不起作用......我做了这个肮脏的黑客来处理流程:

it('should return an error if you try and execute an invalid Query object', function () {
  var stubQuery = {}; 

  try {
    Provider.execute(stubQuery, function (err) {
      if (err) throw "Invalid query error " + err
    });
    // No error, keep on the flow
    noError ();
  } catch (e) {
    // Error, let's continue the flow there
    error (e)
  }

  function noError () {
    // The flow in the event we have no error
    // ... //
  }

  function error (errorObj) {
    // The flow, in the event we have error
    // ... //
  }

});

希望这可以帮助!

于 2012-10-25T13:58:59.570 回答