2011-09-30 90 views
0

我是全新的全新品牌 - javascript,node.js,coffeescript,nodeunit。想想我應該一步一步來做?你可能是對的,但我仍然不會去做。在nodeunit中處理異步性的正確方法是什麼?

下面是測試文件:

testCase = require('nodeunit').testCase 

Server = require('./web').WebServer 
Client = require('../lib/client').Client 
Request = require('../lib/request').Request 

OPTIONS = {host: 'localhost', port: 8080, path: '/', method: 'GET'} 
SERVER = new Server OPTIONS.port 
CLIENT = new Client 
REQUEST = new Request OPTIONS 
SERVER.start() # asynchronous! 

module.exports = testCase 
    setUp: (callback) -> 
    callback() 

    tearDown: (callback) -> 
    callback() 

    testResponseBodyIsCorrect: (test) -> 
    test.expect 1 
    process.nextTick -> 
     CLIENT.transmit REQUEST #asynchronous! 
     process.nextTick -> 
     test.equal REQUEST.body, /Ooga/ 
     test.done() 

在內部,它僅僅是圍繞HTTP庫的包裝。我使用節點0.4.11。 這實際上不起作用。這裏有兩個異步調用。如果我在咖啡REPL中手動執行此操作,它可以工作 - 但nodeunit比我快得多,所以我遇到了一些聰明的事情,我會稱之爲競爭條件。 笑容

這裏是「發送」的實施: 的Http =需要的「http」

exports.Client = class Client 

    transmit: (request, callback = null) -> 
    req = Http.request request.options, (res) -> 
     res.setEncoding 'utf8' 
     res.on 'data', (chunk) -> 
     request.appendToResponseBody chunk 
    req.end() 

    console.log "Request sent!" 

我需要確保服務器被綁定到港之前,我運行測試,和我需要確保「.transmit」在完成斷言之前已完成其內部回調以獲取響應。

什麼是乾淨的方式(或至少有效的方式)來做到這一點?

回答

1

每當你做了異步的事情時,你應該把你的代碼的其餘部分放在該異步函數的回調中。因此,而不是

CLIENT.transmit請求 process.nextTick - > ...

CLIENT.transmit請求(響應) - > ...

(我假設你的CLIENT.transmit方法是以這樣一種方式實現的,即它調用一個回調並獲得它的響應 - 它應該!)

現在,如果您嘗試同時測試客戶端和服務器,那麼你應該使用一個EventEmitter - 我認爲你會發現你的SERVER對象已經是一個了,因爲它繼承了Node的http.Server類型。由於http.Server對象會觸發一個事件request時,他們收到一個請求,你可以做這樣的事情

SERVER.on 'request', (request) -> 
    test.equals REQUEST.body, request.body 

多麼美妙,不是嗎?節點式的異步性可以讓人大跌眼鏡,但它給了你一個驚人的選擇。

+0

事情開始融合(我喜歡那個詞,很少用它)。我已經編輯了這個問題來添加「傳輸」的實現 - 我相當肯定它是壞的。我想我明白了。所以'迴應'回調是回調,這意味着我應該通過 - 回傳另一個回調沒有意義。正確? – Trevoke

+0

哦!這意味着,如果我想構建更高級的接口,最終,我的客戶端或請求封裝器/接口也應該實現或繼承此類事件,而不是依賴於http的低級別事件。由於http.request()發生在客戶端,事件可能不會神奇地冒出來,對吧? – Trevoke

+1

對,Node的好處在於沒有魔法;一切都在表面上。所以目前,傳遞給'transmit'的'callback'參數永遠不會被調用。你需要的是'res.on'end', - >回調? res',它會在響應被完全接收時將響應傳遞給'callback'函數(如果存在)。 –

相關問題