使用mocha中的websockets测试服务器端的客户端连接

时间:2018-04-01 10:18:26

标签: node.js unit-testing socket.io mocha

我使用socket.io库创建了一个简单的示例应用程序,现在我想测试在客户端连接时调用我的io.on("connection")

所以我在我的单元测试中创建了一个简单的假客户端,成功连接到服务器,但是监视由handleSocket触发的方法io.on("connection")的间谍说它从未被触发过,这显然是已根据日志。

这可能是我无法弄清楚的时间/异步问题。

服务器端代码:

const express = require("express");
const app = express();
const port = process.env["PORT"] || 3030;
var io = require("socket.io").listen(port);
io.on("connect", socket => handleSocket(socket));
function handleSocket(socket) {
  console.log("a user connected", socket.id);
}
exports.io = io;
exports.handleSocket = handleSocket;

mocha中的实际单元测试:

var expect = require("chai").expect;
var sinon = require("sinon");
var ioClient = require("socket.io-client");
process.env["PORT"] = 3030;
process.env["VERBOSE"] = true;
var options = {
  transports: ["websocket"],
  "force new connection": false
};
describe("server.spec", function() {
  this.timeout(5000);
  it("Client should connect", function(done) {
    app = require("./server2");
    let spy = sinon.spy(app.handleSocket);
    var client = ioClient.connect("http://localhost:" + process.env["PORT"], options);
    client.on("connect", function() {
      expect(spy.called).to.be.equal(true);
      client.disconnect();
      app.io.close();
      done();
    });
  });
});

测试 - 失败,spy.called等于false 日志输出:

  server.spec
a user connected jopFRhcfzjkC_TjsAAAA
Spy was called: false
    1) Client should connect
a user connected uIpW2gsiljJkS4wFAAAB
Spy was called: false

1 个答案:

答案 0 :(得分:0)

我认为这里的文档:http://sinonjs.org/releases/v4.5.0/spies/,关于创建间谍的部分对于这个用例有点不清楚:

var spy = sinon.spy(myFunc);

如果你创建一个间谍,这意味着spy是你自己需要调用的函数。即,它在myFunc周围创建一个代理,但如果直接调用myFunc,它实际上并不使用该代理。你需要的是:var spy = sinon.spy(object, "method");,所以你的例子将成为:

服务器代码:

const express = require("express");
const app = express();
const port = process.env["PORT"] || 3030;
var io = require("socket.io").listen(port);

exports.handleSocket = function(socket) {
  console.log("a user connected", socket.id);
};

// NOTE: we use handleSocket as method of exports here
io.on("connect", socket => exports.handleSocket(socket));

exports.io = io;

测试规范:

var expect = require("chai").expect;
var sinon = require("sinon");
var ioClient = require("socket.io-client");
process.env["PORT"] = 3030;
process.env["VERBOSE"] = true;
var options = {
  transports: ["websocket"],
  "force new connection": false
};
describe("server.spec", function() {
  this.timeout(5000);
  it("Client should connect", function(done) {
    app = require("./server2");
    let spy = sinon.spy(app, "handleSocket"); // <- CHANGED CODE
    var client = ioClient.connect("http://localhost:" + process.env["PORT"], options);
    client.on("connect", function() {
      expect(spy.called).to.be.equal(true);
      client.disconnect();
      app.io.close();
      done();
    });
  });
});

以这种方式创建间谍时,它实际上替换了对象(handleSocket)上的方法(app),该对象与服务器代码中的导出对象是同一对象。