Node.js 및 WebSocket (Socket.io) 단위 테스트
WebSockets (Socket.io)를 사용하여 Node.js에 대해 견고하고 단순한 단위 테스트를 제공 할 수 있습니까?
Node.js에 socket.io를 사용하고 있으며 테스트에서 서버에 대한 클라이언트 연결을 설정하기 위해 socket.io-client를 살펴 보았습니다. 그러나 나는 무언가를 놓치고있는 것 같다.
아래 예에서 "worked ..."는 인쇄되지 않습니다.
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)
어떤 제안?
추가로 찌르고 찌르고 나서 http://blog.foundry376.com/2012/09/connecting-to-a-socket-io-server-from-node-js-unit-tests 에서 매우 유용한 정보를 찾았습니다 . 저자의 예에서 그는 "before *"후크에 소켓 리스너를 설정하는 중요한 단계를 지적합니다. 이 예제는 작동합니다 (물론 서버가 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 () 배치가 연결을 설정하는 데 중요하다는 것을 알았습니다. 예를 들어 리스너에서 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 ()을 배치하기 위해 시작된 매우 분명한 이유가있을 것입니다. 이 작은 디테일이 머리카락을 잡아 당기는 것으로부터 내 신발에있는 다른 사람들을 구할 수 있기를 바랍니다.
나를 위해 위의 테스트 (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)
여기에서 허용되는 답변의 확장을 제공합니다. 다른 향후 테스트를위한 상용구로 유용한 기본 클라이언트 대 서버 통신이 있습니다. 모카, 차이, 기대를 사용합니다.
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"로 단위 테스트를 수행하는 방법은 무엇입니까?
나는 mocha 와 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);
});
});
약속 과 모범 사례를 기반으로하는 이 상용구 솔루션을 확인하십시오 . 땀없이 서버 전체 io 이벤트를 테스트 할 수 있습니다. 상용구 테스트를 복사하고 필요에 따라 고유 한 코드를 추가하기 만하면됩니다.
전체 소스 코드는 GitHub의 저장소를 확인하세요.
https://github.com/PatMan10/testing_socketIO_server
const io = require("socket.io-client");
const ev = require("../utils/events");
const logger = require("../utils/logger");
// initSocket returns a promise
// success: resolve a new socket object
// fail: reject a error
const initSocket = () => {
return new Promise((resolve, reject) => {
// create socket for communication
const socket = io("localhost:5000", {
"reconnection delay": 0,
"reopen delay": 0,
"force new connection": true
});
// define event handler for sucessfull connection
socket.on(ev.CONNECT, () => {
logger.info("connected");
resolve(socket);
});
// if connection takes longer than 5 seconds throw error
setTimeout(() => {
reject(new Error("Failed to connect wihtin 5 seconds."));
}, 5000);
}
);
};
// destroySocket returns a promise
// success: resolve true
// fail: resolve false
const destroySocket = socket => {
return new Promise((resolve, reject) => {
// check if socket connected
if (socket.connected) {
// disconnect socket
logger.info("disconnecting...");
socket.disconnect();
resolve(true);
} else {
// not connected
logger.info("no connection to break...");
resolve(false);
}
});
};
describe("test suit: Echo & Bello", () => {
test("test: ECHO", async () => {
// create socket for communication
const socketClient = await initSocket();
// create new promise for server response
const serverResponse = new Promise((resolve, reject) => {
// define a handler for the test event
socketClient.on(ev.res_ECHO, data4Client => {
//process data received from server
const { message } = data4Client;
logger.info("Server says: " + message);
// destroy socket after server responds
destroySocket(socketClient);
// return data for testing
resolve(data4Client);
});
// if response takes longer than 5 seconds throw error
setTimeout(() => {
reject(new Error("Failed to get reponse, connection timed out..."));
}, 5000);
});
// define data 4 server
const data4Server = { message: "CLIENT ECHO" };
// emit event with data to server
logger.info("Emitting ECHO event");
socketClient.emit(ev.com_ECHO, data4Server);
// wait for server to respond
const { status, message } = await serverResponse;
// check the response data
expect(status).toBe(200);
expect(message).toBe("SERVER ECHO");
});
test("test BELLO", async () => {
const socketClient = await initSocket();
const serverResponse = new Promise((resolve, reject) => {
socketClient.on(ev.res_BELLO, data4Client => {
const { message } = data4Client;
logger.info("Server says: " + message);
destroySocket(socketClient);
resolve(data4Client);
});
setTimeout(() => {
reject(new Error("Failed to get reponse, connection timed out..."));
}, 5000);
});
const data4Server = { message: "CLIENT BELLO" };
logger.info("Emitting BELLO event");
socketClient.emit(ev.com_BELLO, data4Server);
const { status, message } = await serverResponse;
expect(status).toBe(200);
expect(message).toBe("SERVER BELLO");
});
});
---- 각주 ----
서버 환경을 설정하는 방법에 따라 동일한 프로젝트에서 동시에 실행되는 socket.io와 socket.io-client간에 환경 충돌이 발생할 수 있습니다. 어떤 경우에는 프로젝트를 "테스트 클라이언트"와 서버로 분리하는 것이 좋습니다. 이 문제가 발생하면 저장소 아래에서 확인하십시오.
https://github.com/PatMan10/testing_socketIO_server_v2
참고URL : https://stackoverflow.com/questions/15509231/unit-testing-node-js-and-websockets-socket-io
'IT Share you' 카테고리의 다른 글
파이썬에서 정수 분할? (0) | 2020.12.13 |
---|---|
XAML의 #region (0) | 2020.12.13 |
Go 채널은 어떻게 구현 되나요? (0) | 2020.12.12 |
jQuery에서 $ .getJSON ()과 $ .ajax ()의 차이점 (0) | 2020.12.12 |
InputStream을 FileInputStream으로 변환하는 방법 (0) | 2020.12.12 |