2013-03-19 3 views
45

Может ли кто-нибудь предоставить твердотельный, мертвый простой модульный тест для Node.js с использованием WebSockets (Socket.io)?Тестирование модулей Node.js и WebSockets (Socket.io)

Я использую socket.io для Node.js и посмотрел на 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

Этот тест мокко или жасмина? Для асинхронных тестов мокко (что это такое) ваша тестовая функция должна принимать функцию обратного вызова (testDone), поэтому мокко знает, как правильно ее обрабатывать. На самом деле это может работать, но мокка выходит, прежде чем произойдет событие «connect», потому что мокко не знает, что он должен ждать. –

ответ

47

После дальнейших выталкиваний и подталкивания я нашел невероятно полезную информацию по адресу http://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-tests. В примере автора он указывает на критический шаг установки сокет-слушателей в «до *» крючках. Этот пример работает (предполагая, что сервер прослушивает соединения сокета на локальном хосте: 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(); 
     }); 

    }); 

}); 

Я обнаружил, что размещение сделано() в beforeEach, socket.on («Connect» ...) слушатель имел решающее значение для установления связи. Например, если вы закомментируете done() в прослушивателе, добавьте его в одну область (непосредственно перед тем, как выйти из 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(); 
}); 

Я новичок в Mocha, так что, вероятно, очень очевидная причина посвящённый для размещения сделали() 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() в предыдущем контексте. – bucabay

1

У меня была эта проблема: Как сделать модульное тестирование с «Socket.io-клиент», если вы не Не знаете, как долго сервер реагирует ?.

Я решил так, используя мокко и 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); 
    }); 
}); 
4

Предлагая расширение принятого ответа здесь. Имеет базовую клиентскую связь с сервером, полезную в качестве шаблона для других будущих тестов. Использование мокко, chai и ожидание.

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

}); 
Смежные вопросы