我正在阅读how to mock google cloud functions for firebase,并且正确地模拟了以下代码:
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();
链接中的示例使用以下代码来模拟可行的initializeApp
admin = require('firebase-admin');
adminInitStub = sinon.stub(admin, 'initializeApp');
现在,admin.firestore在firebase-namespace.js中定义如下:
Object.defineProperty(FirebaseNamespace.prototype, "firestore", {
get: function () {
var ns = this;
var fn = function (app) {
return ns.ensureApp(app).firestore();
};
return Object.assign(fn, require('@google-cloud/firestore'));
},
enumerable: true,
configurable: true
});
我已尝试过各种各样的东西来存根,但我失败了
firestore is not a function
中的结果:
Object.defineProperty(admin, "firestore", {
get: function () {
return 32;
}
});
根本不模拟firestore()并调用难以理解的原始函数:
sinon.stub(admin, 'firestore').returns({get() { }});
TypeError:不能存根不存在的自有属性get
firestoreStub = sinon.stub(admin.firestore, 'get').callsFake(function () {return {data:"Foo"}});
我不了解admin.firebase()
实际上是什么。它看起来不像是属性,因为AFAI当我模拟属性的getter时,我会调用admin.firebase
而不是函数admin.firebase()
。但它也不能通过函数来模拟。
答案 0 :(得分:12)
这真的花了我太久。
为了能够模拟admin.firebase()
属性的getter函数,实际应该返回一个函数。
我最初的假设是firebase()
是一个函数,它不是。然后通过查看实现我理解这是一个带有自定义getter的属性。但是我试图通过getter返回一些json数据块。
我最初没有理解admin.firestore
确实是一个属性但是我错过了为什么我必须将属性称为函数的关键,这通常在属性本身不需要。
在达到这一点之后,我明白了属性的getter实际上返回了一个函数,并且可以读取admin.firebase()
var method = admin.firebase; // calling the property getter function
method(); // assuming the getter returned a function object
所以对于我未来的自我;)这就是诀窍:
sinon.stub(admin, 'firestore')
.get(function() {
return function() {
return "data";
}
});
最初我试图做
sinon.stub(admin, 'firestore').get( function () { return "data"; } );
失败,因为admin.firestore()
最终在"data"()
中产生,这没有任何意义。