2011-09-30 16 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を使用しています。 これは実際には機能しません。ここには2つの非同期呼び出しがあります。これをコーヒーREPLで手作業で行うと動作しますが、ノードユニットは私よりもはるかに高速ですので、私は巧妙になるために競合状態を呼び出すようなものに走ります。私は の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オブジェクトは既にノードのhttp.Serverタイプから継承されているため、そのオブジェクトはすでに1つであることがわかります。彼らは要求を受信するたびにhttp.Serverオブジェクトがrequestイベントを発生するので、あなたは右、かなりいい

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

のようなものを行うことができますか?ノードスタイルの非同期性は心を曲げることができますが、それはあなたに素晴らしいオプションの配列を与えます。

+0

物事が合体し始めています(私はその言葉が大好きで、ほとんど使用しません)。私は、「送信」の実装を追加するための質問を編集しました。これはかなり確信していますが、悪いことです。私は私が見ていると思う.. '応答の'コールバックはコールバックです。つまり、それを渡す必要があり、別のコールバックを渡すことは無意味です。正しい? – Trevoke

+0

ああ!そして、それは、最終的に、より高いインターフェースを構築したい場合、クライアントまたはリクエストラッパー/インターフェースも、HTTPの低レベルのものに頼るのではなく、そのようなイベントを実装または継承する必要があることを意味します。http.request()クライアントの内部で起こる、イベントはおそらく魔法のようにバブルアップしないだろうか? – Trevoke

+1

いいえ、Nodeについての素晴らしい点は、魔法がないことです。すべてが表面上にあります。したがって、現在、 'call'に渡された' callback'引数は決して呼び出されません。必要なのは 'res.on 'end'、 - >コールバックですか?それは完全に受信されたときに 'callback'関数(存在する場合)に応答を渡します。 –