2011-09-30 155 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'函数(如果存在)。 –

相关问题