Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing Node.js and WebSockets (Socket.io)

Could anyone provide a rock-solid, dead-simple unit test for Node.js using WebSockets (Socket.io)?

I'm using socket.io for Node.js, and have looked at socket.io-client for establishing the client connection to a server in the test. However, I seem to be missing something.

In the example below, "worked..." never gets printed out.

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

Instead, I simply get:

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

Any suggestions?

like image 909
mysterlune Avatar asked Mar 19 '13 19:03

mysterlune


People also ask

Is Node js good for WebSockets?

Node. js can maintain many hundreds of WebSockets connections simultaneously. WebSockets on the server can become complicated as the connection upgrade from HTTP to WebSockets requires handling. This is why developers commonly use a library to manage this for them.

Should I use Socket.IO or WebSockets?

First of all, every modern browser supports WebSockets these days. Socket.IO uses much more boilerplate code and resources to make it fall back to other technologies. Most of the time, you don't need this level of support. Even in terms of network traffic, Socket.IO is way more expensive.

How do I test a Socket.IO connection?

You can check the socket. connected property: var socket = io. connect(); console.

How do I use Socket.IO with node js?

In order to do it, you need to create an index. js file and install socket.io and express. You can use the following command: touch index. js && npm install express socket.io && npm install --save-dev nodemon .


1 Answers

After further poking and prodding, I found some incredibly useful information. In the author's example, he points out the critical step of establishing socket listeners in the before hooks.

This example works:

Assuming a server is listening for socket connections at localhost:3001, of course

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

I found that the placement of done() in the beforeEach, socket.on('connect'...) listener was crucial to having the connection get established. For example, if you comment out done() in the listener, then add it one scope out (just before exiting the beforeEach), you'll see the "no connection to break..." message instead of the "disconnecting..." message. Like so:

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

I'm new to Mocha, so there's probably a very obvious reason to the initiated for placing done() within the socket scope itself. Hopefully that little detail will save others in my shoes from hair pulling.

For me, the above test (with correct scoping of done()) outputs:

  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) 
like image 58
mysterlune Avatar answered Sep 21 '22 17:09

mysterlune