使用 mocha 中的 websockets 在服务器端测试客户端连接
Testing client connection on the server side with websockets in mocha
我使用 socket.io 库制作了一个简单的示例应用程序,现在我想测试我的 io.on("connection")
在客户端连接时被调用。
所以我在我的单元测试中创建了一个简单的假客户端,它成功连接到服务器,但是监视由 io.on("connection")
触发的方法 handleSocket
的间谍说它从未被触发,这根据日志显然是这样。
这可能是一个我无法弄清楚的 timing/async 问题。
服务器端代码:
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
我认为这里的文档: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();
});
});
});
当您以这种方式创建间谍时,它实际上替换了对象 (app
) 上的方法 (handleSocket
),该对象与从您的服务器代码导出的对象相同。
我使用 socket.io 库制作了一个简单的示例应用程序,现在我想测试我的 io.on("connection")
在客户端连接时被调用。
所以我在我的单元测试中创建了一个简单的假客户端,它成功连接到服务器,但是监视由 io.on("connection")
触发的方法 handleSocket
的间谍说它从未被触发,这根据日志显然是这样。
这可能是一个我无法弄清楚的 timing/async 问题。
服务器端代码:
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
我认为这里的文档: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();
});
});
});
当您以这种方式创建间谍时,它实际上替换了对象 (app
) 上的方法 (handleSocket
),该对象与从您的服务器代码导出的对象相同。