2013-03-19 15 views
45

Có ai có thể cung cấp thử nghiệm đơn vị chết, đơn giản cho Node.js bằng cách sử dụng WebSockets (Socket.io) không?Kiểm thử đơn vị Node.js và WebSockets (Socket.io)

Tôi đang sử dụng socket.io cho Node.js và đã xem xét socket.io-client để thiết lập kết nối máy khách với máy chủ trong thử nghiệm. Tuy nhiên, tôi dường như thiếu một cái gì đó.

Trong ví dụ bên dưới, "đã hoạt động ..." không bao giờ được in ra.

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); 
     }); 

    }); 
}); 

Thay vào đó, tôi chỉ đơn giản nhận được:

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


    1 test complete (26 ms) 

Bất kỳ lời đề nghị?

+2

Đây có phải là thử nghiệm mocha hoặc hoa nhài không? Đối với các kiểm tra mocha không đồng bộ (đây là) hàm test của bạn cần có hàm gọi lại (testDone) 'để mocha biết cách xử lý nó một cách thích hợp. Điều này thực sự có thể được làm việc nhưng mocha là thoát trước khi sự kiện 'kết nối' cháy vì mocha không biết nó nên chờ đợi. –

Trả lời

47

Sau khi tiếp tục chọc và thúc đẩy, tôi đã tìm thấy một số thông tin cực kỳ hữu ích tại http://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-tests. Trong ví dụ của tác giả, ông chỉ ra bước quan trọng trong việc thiết lập trình lắng nghe socket trong các móc "trước *". Ví dụ này công trình (giả sử một máy chủ đang lắng nghe cho các kết nối ổ cắm ở localhost: 3001, tất nhiên)

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(); 
     }); 

    }); 

}); 

tôi thấy rằng vị trí của done() trong beforeEach, socket.on ('kết nối' ...) người nghe rất quan trọng để có kết nối được thiết lập. Ví dụ: nếu bạn nhận xét xong() trong trình nghe, sau đó thêm một phạm vi ra (ngay trước khi thoát khỏi beforeEach), bạn sẽ thấy thông báo "không có kết nối để ngắt ..." thay vì "ngắt kết nối .. ." thông điệp. Giống như vậy:

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(); 
}); 

Tôi mới làm quen với Mocha, vì vậy có thể là một lý do rất rõ ràng để bắt đầu thực hiện() với chính phạm vi ổ cắm. Hy vọng rằng chi tiết nhỏ sẽ tiết kiệm cho những người khác trong giày của tôi từ kéo tóc.

Đối với tôi, những thử nghiệm trên (với Phạm vi đúng đắn về done()) kết quả đầu ra:

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

Thêm {'forceNew': true} vào các tùy chọn khi tạo ổ cắm mới. Bằng cách này, bạn có thể tạo nhiều ổ cắm máy khách trong các bài kiểm tra đơn vị. – HChen

+0

@mysterlune Việc thực hiện() trong phạm vi của socket.on ('connect' ...) đảm bảo socket kết nối trước khi các thử nghiệm bắt đầu chạy. Thao tác được xếp hàng đợi cho đến khi thực hiện() được gọi trong ngữ cảnh trước đó. – bucabay

1

Tôi có vấn đề này: Làm thế nào để làm bài kiểm tra đơn vị với một "socket.io-client" nếu bạn don Không biết bao lâu máy chủ sẽ phản hồi ?.

Tôi đã giải quyết để sử dụng mochachai:

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

Cung cấp một phần mở rộng của câu trả lời được chấp nhận ở đây. Có khách hàng cơ bản để giao tiếp máy chủ hữu ích như boilerplate cho các thử nghiệm khác trong tương lai. Sử dụng mocha, chai và mong đợi.

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; 
    }); 
    }); 

});