2013-03-19 17 views
45

WebSocket(Socket.io)を使用してNode.jsの頑丈でデッドシンプルなユニットテストを提供できる人はいますか?ユニットテストNode.jsとWebSockets(Socket.io)

私はNode.jsにsocket.ioを使用していますが、テストでサーバへのクライアント接続を確立するためにsocket.io-clientを見てきました。しかし、私は何かが欠けているようです。

以下の例では、「作業済み...」は決して印刷されません。

var io = require('socket.io-client') 
, assert = require('assert') 
, expect = require('expect.js'); 

describe('Suite of unit tests', function() { 

    describe('First (hopefully useful) test', function() { 

     var socket = io.connect('http://localhost:3001'); 
     socket.on('connect', function(done) { 
      console.log('worked...'); 
      done(); 
     }); 

     it('Doing some things with indexOf()', function() { 
      expect([1, 2, 3].indexOf(5)).to.be.equal(-1); 
      expect([1, 2, 3].indexOf(0)).to.be.equal(-1); 
     }); 

    }); 
}); 

代わりに、私は単純に取得:

Suite of unit tests 
    First (hopefully useful) test 
     ✓ Doing some things with indexOf() 


    1 test complete (26 ms) 

任意の提案ですか?

+2

このモカまたはジャスミンのテストはありますか?非同期のモカテスト(これはこれです)の場合、テスト関数はコールバック 'function(testDone)'を呼び出す必要があります。そのため、モカはそれを適切に処理することを認識しています。これは実際には動作しているかもしれませんが、mochaは待機する必要があることを知らないため、 'connect'イベントが発生する前にmochaが終了しています。 –

答えて

47

さらに突っ込んで突き刺した後、私はhttp://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-testsに信じられないほど役に立つ情報を見つけました。著者の例では、 "before *"フックにソケットリスナーを確立するための重要なステップを指摘しています。私はbeforeEach、socket.on(「接続」内)(済の配置ことがわかった。(もちろん、3001サーバがローカルホストのソケット接続を待機していると仮定した場合)

var io = require('socket.io-client') 
, assert = require('assert') 
, expect = require('expect.js'); 

describe('Suite of unit tests', function() { 

    var socket; 

    beforeEach(function(done) { 
     // Setup 
     socket = io.connect('http://localhost:3001', { 
      'reconnection delay' : 0 
      , 'reopen delay' : 0 
      , 'force new connection' : true 
     }); 
     socket.on('connect', function() { 
      console.log('worked...'); 
      done(); 
     }); 
     socket.on('disconnect', function() { 
      console.log('disconnected...'); 
     }) 
    }); 

    afterEach(function(done) { 
     // Cleanup 
     if(socket.connected) { 
      console.log('disconnecting...'); 
      socket.disconnect(); 
     } else { 
      // There will not be a connection unless you have done() in beforeEach, socket.on('connect'...) 
      console.log('no connection to break...'); 
     } 
     done(); 
    }); 

    describe('First (hopefully useful) test', function() { 

     it('Doing some things with indexOf()', function(done) { 
      expect([1, 2, 3].indexOf(5)).to.be.equal(-1); 
      expect([1, 2, 3].indexOf(0)).to.be.equal(-1); 
      done(); 
     }); 

     it('Doing something else with indexOf()', function(done) { 
      expect([1, 2, 3].indexOf(5)).to.be.equal(-1); 
      expect([1, 2, 3].indexOf(0)).to.be.equal(-1); 
      done(); 
     }); 

    }); 

}); 

を...この例では動作します)リスナーは、接続を確立するために非常に重要でした。たとえば、リスナーでdone()をコメントアウトしてから、スコープを1つ追加すると(beforeEachを終了する直前)、「切断しています...」の代わりに「no connection to break ...」というメッセージが表示されます。 "メッセージ。これと同じように:

beforeEach(function(done) { 
    // Setup 
    socket = io.connect('http://localhost:3001', { 
     'reconnection delay' : 0 
     , 'reopen delay' : 0 
     , 'force new connection' : true 
    }); 
    socket.on('connect', function() { 
     console.log('worked...'); 
     //done(); 
    }); 
    socket.on('disconnect', function() { 
     console.log('disconnected...'); 
    }); 
    done(); 
}); 

私はモカに新たなんだ、これは非常に明白な理由は、ソケットスコープ自体withiin()で行わ置くための開始におそらくあります。その細かいディテールが、私の靴の中の他人を髪を引っ張って救うことを望みます。

は私にとっては、上記のテストは、出力(完了()の正しいスコープで):

Suite of unit tests 
    First (hopefully useful) test 
     ◦ Doing some things with indexOf(): worked... 
     ✓ Doing some things with indexOf() 
disconnecting... 
disconnected... 
     ◦ Doing something else with indexOf(): worked... 
     ✓ Doing something else with indexOf() 
disconnecting... 
disconnected... 


    2 tests complete (93 ms) 
+1

新しいソケットを作成するときに{'forceNew':true}をオプションに追加します。このようにして、単体テストで複数のクライアントソケットを作成できます。 – HChen

+0

@mysterlune socket.on( 'connect' ...)のスコープ内のdone()は、テストの実行を開始する前にソケットが確実に接続します。 done()が前のコンテキスト内で呼び出されるまで、操作はキューに入れられます。 – bucabay

1

私はこの問題を持っていた:あなたドン場合は、「socket.io-クライアント」でユニットテストを行う方法サーバーが応答するまでの時間は分かりません。

var os = require('os'); 
var should = require("chai").should(); 
var socketio_client = require('socket.io-client'); 

var end_point = 'http://' + os.hostname() + ':8081'; 
var opts = {forceNew: true}; 

describe("async test with socket.io", function() { 
this.timeout(10000); 

it('Response should be an object', function (done) { 
    setTimeout(function() { 
     var socket_client = socketio_client(end_point, opts); 

     socket_client.emit('event', 'ABCDEF'); 

     socket_client.on('event response', function (data) { 
      data.should.be.an('object'); 
      socket_client.disconnect(); 
      done(); 
     }); 

     socket_client.on('event response error', function (data) { 
      console.error(data); 
      socket_client.disconnect(); 
      done(); 
      }); 
     }, 4000); 
    }); 
}); 
4

ここ受け入れ答えの拡張を提供:

私はそうモカチャイを使用して解決しました。基本的なクライアントからサーバーへの通信は、将来の他のテストのための定型文として有用です。モカ、チャイを使用して、期待してください。

var io = require('socket.io-client') 
    , io_server = require('socket.io').listen(3001); 

describe('basic socket.io example', function() { 

    var socket; 

    beforeEach(function(done) { 
    // Setup 
    socket = io.connect('http://localhost:3001', { 
     'reconnection delay' : 0 
     , 'reopen delay' : 0 
     , 'force new connection' : true 
     , transports: ['websocket'] 
    }); 

    socket.on('connect',() => { 
     done(); 
    }); 

    socket.on('disconnect',() => { 
     // console.log('disconnected...'); 
    }); 
    }); 

    afterEach((done) => { 
    // Cleanup 
    if(socket.connected) { 
     socket.disconnect(); 
    } 
    io_server.close(); 
    done(); 
    }); 

    it('should communicate', (done) => { 
    // once connected, emit Hello World 
    io_server.emit('echo', 'Hello World'); 

    socket.once('echo', (message) => { 
     // Check that the message matches 
     expect(message).to.equal('Hello World'); 
     done(); 
    }); 

    io_server.on('connection', (socket) => { 
     expect(socket).to.not.be.null; 
    }); 
    }); 

}); 
関連する問題