Firebase / AngularFire - 如何模拟我链接 $loaded() 的 Firebase 引用?

Firebase / AngularFire - How Do I Mock a Firebase Reference That I Chained $loaded() To?

我使用以下函数连接到我的 Firebase 对象:

$scope.getData= function(param){
    var ref = new Firebase(firebaseConstants.url + 'data/' + param);
    var sync = $firebase(ref.orderByChild('timestamp').limitToLast(1));
    return sync.$asArray();
};

我按以下方式使用上述方法:

$scope.setData= function(param){
    var lastMessage = $scope.getData(param);
    lastMessage.$loaded().then(function(){
        $scope.message = lastMessage.message;
        $scope.images = lastMessage.images;
    }, function(data){
        console.log(data);
    });
};

在我的 Jasmine 测试文件中,我有以下内容:

describe('setData Test', function(){
    it('should please me', function(){
        var param = 932489234;
        spyOn(scope, 'getData').and.returnValue({
            $loaded: function(){
                deferred = q.defer();
                deferred.resolve({
                    $id: 'talk to you',
                    message: 'brother',
                    images: {
                        0: 'www.google.com',
                        1: 'www.paper.com',
                        2: 'www.sun.com'
                    }
                });
                return deferred.promise;
            }
        });
        scope.setData(param);
        scope.$apply();
    });
});

上面的测试允许我模拟 $loaded() 被解析,但是在 promise 解析后我无法获得 lastMessage 的值。

似乎 lastMessage 首先 return 是一个承诺形式的函数,然后 return 值在初始承诺解决后更改为实际响应对象。

如何在我的 Jasmine 测试中模拟它?

您可以跟踪调用 $loaded 函数的次数。如果是第一次调用,return 承诺,如果是第二次调用,return 解析值。

像这样:

_calls: 0,
$loaded: function() {
  var self = this;
  self._calls += 1;
  if (self._calls === 1) {
    // ...
    return deferred.promise.then(function(value) {
      self._resolvedValue = value;
      return value;
    });
  } else {
    return self._resolvedValue;
  }
}

您可以使用链接到 $loaded() 的回调函数参数来解决这个问题。而不是使用:

lastMessage.$loaded().then(function(){}

我用过

lastMessage.$loaded().then(function(data){
    // lastMessage === data
})

data 在这种情况下将与回调函数中的 lastMessage 具有相同的值。这将允许您在 Jasmine 测试中使用以下代码为 data 赋值:

deferred.resolve({
    $id: 'talk to you',
    message: 'brother',
    images: {
        0: 'www.google.com',
        1: 'www.paper.com',
        2: 'www.sun.com'
    }
});