nodejs-tw / ama

Ask me anything!
MIT License
31 stars 1 forks source link

socket.io/eventEmitter 單元測試與回歸測試 #17

Open TerrenceChao opened 7 years ago

TerrenceChao commented 7 years ago

目的

我近期在建立一個關於socket.io應用的專案(類似聊天室),最近要做單元測試和回歸測試

使用的工具

我在 windows 7 下使用 npm 安裝 node.js v6.2.1, socket.io v1.4

unittest 套件 mocha, should

操作流程

為了做socketIo的單元測試,我做了以下操作: describe('unittest', () => {

before('init', () => { //init });

it('eventEmitter listen', ()=>{ emitter.on('someEvent', (receiveObj) => { should(receiveObj).have.property('name', 'userName'); }); });

it('server site', () => {
    socketIo.sockets.on('connection', function(socket) {
        //socket listeners
    });

});

it('client site', () => {
      var jsonObj = ...//initialized
      client.on('connect', function() {
          setTimeout(() => {
                  client.emit('client_event', jsonObj);   
          }, 300 * delay);
     });

}); });

遇到的問題

Microsoft Windows [版本 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved.

D:....event_handler>mocha competeLockTest.js

unittest: CompeteLockEventHandler server site: event handlers √ client site:

1 passing (116ms)

註解: 其實他甚麼都沒有檢查到!!!!!!!!!!!!!! 連client送到server site的event都沒監聽到,eventEmitter也沒聲沒息

嘗試過的解法

我嘗試過把結構改成 describe('unittest', () => { describe('xxx', () => { it('eventEmitter listen', (){...} ) it('server site' (){...} )

    it('client site'  (){...} )
})

})

程式碼

下面附上我的程式碼以及我遇到的"錯誤"

程式碼

const clientIo = require('socket.io-client');

var socketURL = 'http://127.0.0.1:1337'; var serverIo = socketIo.listen(Server);

var password = '0000'; var createRoomInfo_A = {uid: 'Terrence0503', roomName: 'Top Secrit', pwd: password };

var createRoomInfo_B = {uid: 'Leo3355687', roomName: 'Nice Club', pwd: password };

var uid_A = 'Terrence0503', userA = { uid: uid_A, objCode: '0001', }, uid_B = 'Sziyu321654', userB = { uid: uid_B, objCode: '0001', };

function funcCreateRoom(client, createRoomInfo, delay) {

should(createRoomInfo).have.property('uid');
should(createRoomInfo).have.property('roomName');
should(createRoomInfo).have.property('pwd');

client.on('connect', function() {
    setTimeout(() => {
        client.emit('create_room', createRoomInfo);   

    }, 300 * delay);
});

}

describe('unittest: Create Room', () => {

before('init', () => {
    //init variables...
});

it('eventEmitter listen', () => {

    emitter.on('messageEvent', (receiveObj) => {
        shoud(receiveObj).have.property(‘name’, ‘userName’);
        ….
    });

});

it('server site: event handlers', () => {

    serverIo.sockets.on('connection', function(socket) {  

        socket.on('create_room', function(jsonObj) {
            shoud(jsonObj).have.property(‘name’, ‘userName’);
            ….

            createRoomEventHandler.handle(socket, jsonObj);
        });
    });

});

it('client site: ', () => {
    var len = users.length;
    var clients = [];
    for(var i = 0; i < len; i++) {
        var client = clientIo.connect(socketURL);
        clients.push(client);
    }
    var interval = 1;
    funcCreateRoom (clients[0], createRoomInfo_A, interval++);
});

});

錯誤

Microsoft Windows [版本 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved.

D:...\event_handler>mocha competeLockTest.js TestServer running at http://127.0.0.1:1337/

unittest: CompeteLockEventHandler server site: event handlers √ client site:

1 passing (116ms)

他至少應該要在打勾的地方出現我用should/assert測試的語句,但其實他甚麼都沒有檢查到!!!!!!!!!!!!!! 連client送到server site的event都沒監聽到,eventEmitter也沒聲沒息。

jasperck commented 7 years ago

先不論 code 有沒有 bug, 用 mocha 寫 async test case 時,別忘了 done https://mochajs.org/#asynchronous-code

it('eventEmitter listen', (done) => {
  emitter.on('messageEvent', (receiveObj) => {
    shoud(receiveObj).have.property(‘name’, ‘userName’);
    done();
  });
});

我這邊寫了一個可以動的例子,參考參考 https://gist.github.com/jasperck/3ef7261ca2b9eac883928f656e35822a 另外提一下,

  1. 這類碰到要驗證 callback, functions/methods 如何被操作的情境,可以善用 spy, stub,讓 test case 寫起來更簡潔,就不用在 callback 裡寫一堆 assertion。
    const spy = sinon.spy();
    server.getSocket().on(event, spy);
    sinon.assert.calledWith(spy, expectation);
  2. async 的情境就好好利用 promise, async/await (我 gist 的例子用 promise)
    return Promise.resolve()
    .then(() => client.connect())
    .then(() => server.getSocket().on(event, spy))
    .then(() => client.send(event, expectation))
    .then(() => sinon.assert.calledWith(spy, expectation));