unit testingNode.js和WebSockets(Socket.io)
任何人都可以使用WebSockets(Socket.io)为Node.js提供一个坚如磐石,简单的unit testing吗?
我为Node.js使用socket.io,并且在testing中查看了socket.io-clientbuild立到服务器的客户端连接。 但是,我似乎失去了一些东西。
在下面的例子中,“工作…”永远不会被打印出来。
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)
有什么build议么?
进一步戳和刺激后,我发现了一些非常有用的信息在http://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-tests 。 在笔者的例子中,他指出了在“before *”挂钩中build立套接字监听器的关键步骤。 这个例子工作(当然,假设一个服务器正在侦听localhost上的套接字连接: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()对于build立连接至关重要。 例如,如果您在侦听器中注释掉done(),则将其添加一个范围(在退出beforeEach之前),您将看到“无连接断开…”消息,而不是“断开连接”。 。“ 信息。 像这样:
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的新手,因此可能有一个非常明显的原因,就是在套接字范围本身中放置done()。 希望有一点细节可以挽救别人从头发拉我的鞋子。
对于我来说,上面的testing(对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)
在此提供可接受答案的扩展。 具有基本的客户端到服务器通信作为其他未来testing的样板。 用摩卡,柴和期待。
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; }); }); });
我有这个问题:如果你不知道服务器需要多长时间来响应,怎么用“socket.io-client”做unit testing?
我已经解决了如此使用摩卡和柴 :
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); }); });