2016-11-15 15 views
0

我有一個小問題,困擾我.. 下面的代碼顯示了一個異步測試,在該測試中,我們測試代碼我們沒有控制(黑盒測試,我可以改變它)。摩卡,應該 - 當測試有承諾的異步函數,斷言錯誤是沉默

黑盒代碼在事件完成時調度事件,測試偵聽此事件並聲明數據。

問題是當有一個斷言錯誤,異常由承諾錯誤處理程序而不是由測試框架引發並觸發時,所以done函數永遠不會執行,並且我們得到此測試的超時錯誤。

它很容易解決它通過嘗試&捕捉它的內部()塊,但它是一個很好的做法總是有嘗試& catch()塊內?到目前爲止,我相信測試框架來處理異常

另一個問題是,錯誤是沉默的,除非catch打印它,並且因爲它的黑盒我們不能指望它。

的祕訣在這裏幫我解決這個問題,但我不喜歡的解決方案: https://github.com/mochajs/mocha/issues/1128#issuecomment-40866763

它比其他類似的問題不同,因爲在它()塊中,我們不要有承諾的對象的任何引用。

describe.only("test", function() { 

    var event; 

    // blackbox simulates a code we have no controler over 
    // inside this code we have a promise, when this promise resolves it triggers event 
    var blackbox = function() { 
    var promise = new Promise(function (resolve, reject) { 
     resolve(); 
    }); 

    promise.then(function() { 
     event(4); 
    }).catch(function (e) { 
     console.log(e); 
    }); 
    }; 

    it("async with blackbox promise", function (done) { 
    // this simulates event listenner, when the event is triggered the code executes 
    event = function (data) { 
     // this assertion works and everything is fine 
     data.should.be.equal(4); 
     // this assertion thrown exception that is being cought by the promise reject handler and 
     // isnt cought by the testing framework (chai/mocha) 
     data.should.be.equal(5); 
     // because the exception is thrown we never reach the done 
     done(); 
    }; 

    blackbox(); 

    }); 
}); 
+0

我覺得你是一個有點混淆東西的。總是回覆你的承諾,當測試承諾時,你不需要'完成'回調。只需返回你所有的承諾。 – MarcoL

+0

另外請注意,如果你想讓'mocha'在一個被拒絕的'promise'上失敗,那麼你就不必''抓住''自己。 – MarcoL

+0

@MarcoL,這只是一個例子,因爲代碼是blackboxed - 我沒有控制它。它可以是第三方庫/依賴項 或者你的意思是黑盒子示例代碼寫錯了嗎? –

回答

1

您在mocha測試承諾的方式是,您返回它們並讓它做出決定何時失敗的工作。

所以第一步是使承諾在您所在blackbox功能:

// blackbox simulates a code we have no controler over 
// inside this code we have a promise, when this promise resolves it triggers event 
var blackbox = function() { 
    var promise = new Promise(function (resolve, reject) { 
    resolve(); 
    }); 

    return promise.then(function() { 
    event(4); 
    }); 
    // do not catch here unless you want the test to not fail on error 
}; 

現在,讓我們更改測試代碼來處理承諾:

it("async with blackbox promise", function() { 
    // this simulates event listenner, when the event is triggered the code executes 
    event = function (data) { 
    // this assertion works and everything is fine 
    data.should.be.equal(4); 
    // this assertion thrown exception that is being cought by the promise reject handler 
    data.should.be.equal(5); 
    }; 
    // mocha will append a rejection handler to this promise here and fail if it gets called 
    return blackbox(); 

});