代码之家  ›  专栏  ›  技术社区  ›  Samuel

无法模拟管理员。单元测试期间的firestore()

  •  14
  • Samuel  · 技术社区  · 7 年前

    我在读书 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');
    

    现在是管理员。firestore在firebase命名空间中定义。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
    });
    

    我尝试过各种方法来存根,但我失败了

    1. 结果在 firestore is not a function :

          Object.defineProperty(admin, "firestore", {
              get: function () {
                  return 32;
              }
          });
      
    2. 根本不模拟firestore(),并调用原始函数,但该函数很难失败:

          sinon.stub(admin, 'firestore').returns({get() { }});
      
    3. TypeError:无法存根不存在的自有属性get

         firestoreStub = sinon.stub(admin.firestore, 'get').callsFake(function () {return {data:"Foo"}});
      

    我不明白什么 admin.firebase() 实际上是的。它看起来不像是一个属性,因为AFAI当我模拟一个属性的getter时,我会调用 admin.firebase 而不是一个函数 管理firebase() . 但它也不能通过函数进行模拟。

    1 回复  |  直到 5 年前
        1
  •  22
  •   Kyle Hotchkiss    7 年前

    那真的花了我太长时间。

    能够嘲笑 admin.firebase() 属性的getter函数实际上应该 返回函数 .

    我最初的假设是 firebase() 是一个函数,但它不是。然后通过查看实现,我了解到这是一个具有自定义getter的属性。然而,我试图通过getter返回一些json数据块。

    起初我没能理解这一点 admin.firestore 确实是一个属性,但我缺少了为什么必须将该属性作为函数调用的关键,这通常在属性本身上是不需要的。

    说到这里,我明白了属性的getter实际上返回了一个函数 管理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"() ,这毫无意义。