node.js unit-testing websocket socket.io

Pruebas unitarias Node.js y WebSockets(Socket.io)



unit-testing (3)

¿Alguien podría proporcionar una prueba de unidad sólida como una piedra muerta para Node.js usando WebSockets (Socket.io)?

Estoy usando socket.io para Node.js, y he consultado socket.io-client para establecer la conexión del cliente a un servidor en la prueba. Sin embargo, parece que me falta algo.

En el siguiente ejemplo, "trabajado ..." nunca se imprime.

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

En cambio, simplemente obtengo:

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

¿Alguna sugerencia?


Después de hurgar y pinchar más, encontré información increíblemente útil en http://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-tests . En el ejemplo del autor, señala el paso crítico de establecer detectores de socket en los enlaces "antes *". Este ejemplo funciona (suponiendo que un servidor está escuchando conexiones de socket en localhost: 3001, por supuesto)

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

Descubrí que la colocación de done () en el oyente beforeeach, socket.on (''connect'' ...) era crucial para que se estableciera la conexión. Por ejemplo, si comenta done () en el oyente y luego agrega un alcance (justo antes de salir del beforeEach), verá el mensaje "no hay conexión para interrumpir ..." en lugar de "desconexión". . "mensaje. Al igual que:

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

Soy nuevo en Mocha, por lo que probablemente haya una razón muy obvia para que los iniciados coloquen done () dentro del alcance del socket. Con suerte, ese pequeño detalle salvará a otros en mis zapatos de la extracción del cabello.

Para mí, la prueba anterior (con el alcance correcto de los resultados de done ()):

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)


Ofreciendo una extensión de la respuesta aceptada aquí. Tiene una comunicación básica entre el cliente y el servidor útil como modelo para otras pruebas futuras. Usando mocha, chai y esperar

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


Tuve este problema: ¿Cómo hacer una prueba unitaria con un "socket.io-client" si no sabes cuánto tarda el servidor en responder ?.

Lo he resuelto usando mocha y chai :

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