如何使用磁带测试异步抛出错误的函数?

时间:2016-02-01 16:48:30

标签: node.js node.js-tape

我正在尝试测试此模块(receiver.js)是否存在错误:

var request = require('request')

module.exports = function(url){
    request({
        url: url,
        method: 'POST'
    }, function(error) {
        if(error){
            throw error
        }
    })
}

使用此测试(test.js):

var test = require('tape')

test('Receiver test', function(t){
    var receiver = require('./receiver')
    t.throws(function(){
        receiver('http://localhost:9999') // dummy url
    }, Error, 'Should throw error with invalid URL')
    t.end()
})

但是磁带在抛出错误之前运行断言,导致以下错误消息:

TAP version 13  
# Receiver test  
not ok 1 Should throw error with invalid URL  
  ---  
    operator: throws  
    expected: |-  
      [Function: Error]  
    actual: |-  
      undefined  
    at: Test.<anonymous> (/path/to/tape-async-error-test/test.js:5:4)  
  ...  
/path/to/receiver.js:9  
throw error  
^  

Error: connect ECONNREFUSED 127.0.0.1:9999  
    at Object.exports._errnoException (util.js:856:11)  
    at exports._exceptionWithHostPort (util.js:879:20)  
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1062:14)  

有解决方法吗?

2 个答案:

答案 0 :(得分:0)

通常,使用磁带,必须确保在异步调用完成后调用assert.end()。使用诺言(需要request-promise并返回诺言):

test('Receiver test', function(t){
    // Tells tape to expec a single assertion
    t.plan(1);

    receiver('http://localhost:9999')
        .then(() => {
            t.fail('request should not succeed')
        })
        .catch(err => {
            t.ok(err, 'Got expected error');
        })
        .finally({
            t.end();
        });
});

使用async / await

test('Receiver test', async function(t) {
    try {
        await receiver('http://localhost:9999');
        assert.fail('Should not get here');
    } catch (err) {
        assert.ok(err, 'Got expected error');
    }
    t.end();
});

答案 1 :(得分:0)

以上示例在大多数情况下是正确的,但这是一个完整的工作示例,该示例将异步与同步进行了比较,并显示了如何以类似于磁带的README.md上给出的磁带示例的方式检查错误消息。 >

test('ensure async function  can be tested to throw', async function(t) {
  // t.throw works synchronously
  function normalThrower() {
    throw(new Error('an artificial synchronous error'));
  };
  t.throws(function () { normalThrower() }, /artificial/, 'should be able to test that a normal function throws an artificial error');

  // you have to do this for async functions, you can't just insert async into t.throws
  async function asyncThrower() {
    throw(new Error('an artificial asynchronous error'));
  };  
  try {
    await asyncThrower();
    t.fail('async thrower did not throw');
  } catch (e) {
    t.match(e.message,/asynchronous/, 'asynchronous error was thrown');
  };
});