Sinon.js:无法模拟 node.js 网络对象
Posted
技术标签:
【中文标题】Sinon.js:无法模拟 node.js 网络对象【英文标题】:Sinon.js: cannot mock node.js net object 【发布时间】:2021-11-24 13:49:59 【问题描述】:我对测试很陌生,所以这个问题可能很简单......但我仍然需要一些帮助:
我有一个 node.js 服务器:
const net = require("net");
const Canvas = require("./canvas");
server.on("connection", (socket) =>
const canvas = (new Canvas(socket));
...
);
server.listen(8124);
在 canvas.js 文件中:
class Canvas
constructor(socket)
this.socket = socket;
disconnect()
this.socket.end();
this.socket.destroy();
我正在尝试测试断开功能,并尝试模拟套接字对象的方法:
const Canvas = ...
const expect = require("expect");
const sinon = require("sinon");
describe('Canvas', () =>
const fakeSocket =
end: () => ,
destroy: () => ,
write: () => ,
;
let canvasObj;
const mock = sinon.mock(fakeSocket);
beforeEach(() =>
canvasObj = new Canvas(mock);
);
describe("disconnect", () =>
it("calls the appropriate functions", () =>
mock.expects("end").once();
mock.expects("destroy").once();
canvasObj.disconnect();
mock.verify();
expect(fakeSocket.end).toHaveBeenCalled();
expect(fakeSocket.destroy).toHaveBeenCalled();
);
);
);
不幸的是,当我运行测试时,它显示 TypeError: this.socket.end is not a function。我有什么遗漏吗?
【问题讨论】:
【参考方案1】:当我看到您的示例时,我能想到的可能的断开测试脚本有 2 个版本:
-
使用 sinon.fake(),
// File: canvas.spec.js
const expect = require('expect');
const sinon = require('sinon');
const Canvas = require('./canvas');
describe('Canvas using sinon.fake()', () =>
const fakeSocket =
end: sinon.fake(),
destroy: sinon.fake(),
write: sinon.fake(),
;
let canvasObj;
beforeEach(() =>
canvasObj = new Canvas(fakeSocket);
);
describe('disconnect', () =>
it('calls the appropriate functions', () =>
canvasObj.disconnect();
// Note: You can not directly use toHaveBeenCalled() because this is from jest expect, not sinon.
expect(fakeSocket.end.calledOnce).toBe(true);
expect(fakeSocket.destroy.calledOnce).toBe(true);
);
);
);
-
使用 sinon.mock()
// File: canvas2.spec.js
const expect = require('expect');
const sinon = require('sinon');
const net = require('net');
const Canvas = require('./canvas');
describe('Canvas using sinon.mock()', () =>
let canvasObj;
const socket = new net.Socket();
const mock = sinon.mock(socket);
beforeEach(() =>
// Note: Subject under test is socket, not mock.
canvasObj = new Canvas(socket);
);
describe('disconnect', () =>
it('calls the appropriate functions', () =>
mock.expects('end').once();
mock.expects('destroy').once();
canvasObj.disconnect();
mock.verify();
);
);
);
当我从终端使用 mocha 运行它时:
$ npx mocha *.spec.js
Canvas using sinon.mock()
disconnect
✔ calls the appropriate functions
Canvas using sinon.fake()
disconnect
✔ calls the appropriate functions
2 passing (16ms)
补充说明:fake function / spy 被调用一次的 sinon 期望是:calledOnce 而不是 toHaveBeenCalled()。
【讨论】:
非常感谢!好像我把 sinon 和 jest 的语法搞混了。 如果我的回答有帮助,那么:请vote or accept it。以上是关于Sinon.js:无法模拟 node.js 网络对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 sinon js/loopback testlab 模拟来自 twilio-node 的 messages.create() 方法的返回值?
从网络/TCP/HTTP 连接的角度来看,Node.js 是如何工作的? WCF 可以模拟这个吗?