2016-05-19 28 views
0

我想單元測試一個函數。 在這個函數中,我使用了Co和一個生成器函數。 出現錯誤時我抓住它,我叫CB與錯誤發生器功能的摩卡測試中的無聲錯誤

在我的單元測試我做一個假的斷言,但摩卡不報告它,它只是超時:

//function to test 

function start(data, cb) { 
    co(function * coStart() { 
    yield Promise.reject('err'); // yield error for sake of demo 
    }).then(function(result){ 
    return cb(null, result); 
    }).catch(function (err) { 
    // we get here 
    return cb(err); 
    }); 
} 

// mocha test 

it('fails on incorrect data', function(done){ 
    MyModel.start({'foo': 'bar'}, function(err, res){ 
    assert.equal(err, 'err2'); //this fails but mocha just stops here and times out 
    done(); 
    }); 
}); 

顯然我在這裏做錯了什麼?

我知道你可以返回一個承諾,摩卡,而忽略在測試中做回調,但我的函數「開始」不能返回一個承諾,其狀如中間件所以它應該有一個回調

回答

1

您的代碼工作做一些與此類似:

Promise.reject('err') 
     .catch(() => { 
     // throw another exception 
     throw 'foo'; 
     }); 

這就是:.catch()子句中,另一個異常被拋出(在你的情況下,由異常拋出assert.equal(err, 'err2')),同步,未辦理(通過,實例,另一個.catch()條款)。這會導致第二個異常被忽略(請參閱this answer作爲解釋),但它會停止測試案例的完成(done()行永遠不會到達,因此超時測試案例)。

如果你真的需要回調支持,您可以解決此通過添加在start()另一.catch()條款,或通過調用回調異步:

return setImmediate(function() { cb(null, result) }); 
... 
return setImmediate(function() { cb(err) }); 
... 

但理想情況下,你應該考慮取消回調的可能性完全支持,只是傳遞承諾。摩卡支持開箱即用的承諾,所以代碼看起來像這樣:

function start(data) { 
    return co(function * coStart() { 
    yield Promise.reject('err'); 
    }); 
} 

it('fails on incorrect data', function(){ 
    return start({'foo': 'bar'}).then(function() { 
    throw new Error('should not be reached'); 
    }, function(err) { 
    assert.equal(err, 'err2'); 
    }); 
}); 
+0

Thx男人,我終於明白了這一點! setImmediate可以工作。是否有使用這個,因爲它感覺有點像黑客「正常流動」沒有任何影響 – Ernie

+1

還有像一些替代品['dezalgo'(https://github.com/npm/dezalgo),你可以使用替代,這可能會給一些更乾淨的代碼。我更喜歡自己的「全面承諾」解決方案,但我意識到這並不總是一個選擇:D – robertklep

+0

Thx!我會檢查出來的 – Ernie