node.js - 在 Node js 中模拟 gcp pubsub 对象。开玩笑的
问题描述
我正在尝试为 GCP 云功能编写单元测试。下面是我要测试的代码片段。
//index.js
const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
exports.myFunction = functions.runWith(RUNTIME_OPTS).https.onCall(async (data, context) => {
//pubsubbody = generated..
//some logic
await pubsub.topic(topicname).publish(pubsubBody, {
platform: body.platform,
environment: body.environment,
event: !!event ? event : 'unknown',
});
});
我能够使用 firebase-functions-test 库测试 myFunction 逻辑。我做了这样的事情
//test.js
const fft = require('firebase-functions-test')();
const funcs = require('../../index');
describe('function to test viewAddRequestedProxy', () => {
const wrapped = fft.wrap(funcs.viewAddRequestedProxy);
// simple logic test.
test('NullDataTest', async () => {
const result = await wrapped(null, null);
expect(result).toStrictEqual({output: 'xyz'});
});
});
现在我想测试我在函数中进行 pubsub 调用的行。我尝试了很多东西,但我对 node.js 以及一般的模拟对象真的很陌生。
我不明白如何在我的 index.js 中模拟 pubsub 对象并检查它是否正在发布消息。
await pubsub.topic(topicname).publish(pubsubBody, {
platform: body.platform,
environment: body.environment,
event: !!event ? event : 'unknown',
});
如果我需要导出我的 pubsub 对象并访问它 test.js,我会感到困惑。我试过这个,但由于某种原因"module.exports = { pubsub: pubsub };"
对我不起作用。我还尝试使用 spyOn 在 test.js 中创建一个模拟
const {PubSub} = require('@google-cloud/pubsub');
const singleAdd = (PubSub) => {
PubSub.topic;
};
test('spyOn .toBeCalled()', (object, method) => {
const somethingSpy = jest.spyOn(PubSub, 'topic');
somethingSpy();
const topic = PubSub.topic('abc');
expect(somethingSpy).toBeCalled();
});
虽然我不确定我是否需要这个,但也尝试了手动模拟。通过创建一个Mocks文件夹,但似乎没有任何效果。
任何帮助将不胜感激。我想我完全偏离了轨道。
解决方案
为了模拟一个节点库,您需要在__mocks__/lib-name/index.js
其中放置一个模拟真实界面的文件。
在您的情况下,将pubsub.js
文件放入__mocks__/@google-cloud/
.
//pubsub.js
class PubSubMock {
static mockInstances = [];
static clearAllMocks() {
PubSubMock.mockInstances.forEach((instance) =>
Object.getOwnPropertyNames(
instance.constructor.prototype
).forEach((method) => method.mockClear())
);
PubSubMock.mockInstances.length = 0;
}
constructor() {
Object.getOwnPropertyNames(this.constructor.prototype).forEach((method) => {
spyOn(this, method).and.callThrough();
});
PubSubMock.mockInstances.push(this);
}
topic(topic) {
// you can implement here the logic
return this;
}
publish(body, obj) {
return this;
}
}
module.exports.PubSub = PubSubMock;
Jest 将确保每个要求'@google-cloud/pubsub'
都映射到该模拟文件。
该类的模拟实现PubSub
自动监视所有类方法,这样您就可以测试是否调用了某个方法以及使用什么参数。
问题是您的生产代码创建了一个新实例PubSub
而不公开它,因此您无法获得它的参考。一个小技巧是公开一个静态属性,该属性将保存所有创建的实例,并将由PubSub.mockInstances
.
const {PubSub} = require('@google-cloud/pubsub');
const funcs = require('../../index');
test('spyOn .toBeCalled()', (object, method) => {
funcs() // call for you real code
const mockInstance = PubSub.mockInstances[0];
expect(mockInstance.topic).toHaveBeenCalledWith('arg1');
});
推荐阅读
- usb - 使用 Yubikey Nano 时笔记本电脑空闲功耗调整
- c# - 如何控制 WPF 应用程序启动时默认“选择”的元素 - 即启动时默认键盘光标在哪里?
- php - 如何对php文件中两行或多行的总和运行sql查询
- c# - 模式匹配和范围 - If 语句
- c# - aspnet 核心中的复杂自定义模型绑定与属性类中的继承
- python - VSCode 在进入灰色背景模式时没有提供自动完成提示
- angularjs - 从 1.1.5 到 1.5.1 的 AngularJS 动画出现问题
- javascript - 从一个类调用方法时从另一个类调用方法
- flutter - Flutter 发布应用的崩溃信息分析
- vba - 自定义幻灯片控件