mercredi 21 septembre 2016

How to assert a single websocket message out of several using node

Imaging the following node based websocket server app, which echos any received message back to the client. In parallel it rolls a dice every seconds, reporting the result to the client:

// app.js
var WebSocket = require('ws');

var wsServer = new WebSocket.Server({ port: 3000, host: '127.0.0.1 });
wsServer.on('connection', function (socket) {
    if (socket.readyState === WebSocket.OPEN) {
        (function loop() {
            var dice = Math.floor(Math.random() * 6) + 1;
            socket.send('Rolling the dice: ' + dice);
            setTimeout(loop, 1000);
        })();
    }
    socket.on('message', function (message) {
        socket.send(message);
    });
});

I would like to write a test for the "echo message" part. How would you assert that it echos messages?

Here's my approach: The following mocha test tries to assert that the message is echoed. It fails because it actually receives the result from the dice.

// app-test.js
var assert = require('assert');
var WebSocket = require('ws');
var wsServer = require('./app.js');

describe('Websocket Server', function() {
    it('should echo a message', function(done) {
        var ws = new WebSocket('ws://127.0.0.1:3000');
        ws.on('open', function () {
            var data = 'my test message';
            ws.send(data);
            ws.on('message', function(message) {
                assert.equal(data, message);
                done();
                ws.close();
            });
        });
    });
});

Test result:

  Websocket Server
    1) should echo a message


  0 passing (47ms)
  1 failing

  1) Websocket Server should echo a message:

      Uncaught AssertionError: 'my test message' == 'Rolling the dice: 2'
      + expected - actual

      -my test message
      +Rolling the dice: 2

A solution would be to push any message received into an array within a certain time frame. Then assert the expected value being inside this array. However I'd like to avoid using setTimeout() in the test.

Finally, the package.json:

{
  "name": "ws-echo-test",
  "version": "0.0.1",
  "dependencies": {
    "ws": "^1.1.1"
  },
  "devDependencies": {
    "mocha": "^3.0.2"
  }
}

Aucun commentaire:

Enregistrer un commentaire