Angularjs TypeError:无法读取属性';然后';未定义角度的grunt检验

Angularjs TypeError:无法读取属性';然后';未定义角度的grunt检验,angularjs,unit-testing,karma-runner,q,Angularjs,Unit Testing,Karma Runner,Q,我使用$q服务进行异步调用。我无法使用karma解决单元测试中的“then”和“defer” 下面是我的控制器代码 scope.filterUrls = [{url:'page1'}, {url: 'page2'}, {url:'page-error'}]; scope.bindFilters = function () { angular.forEach(scope.filterUrls, function (data) { scope.getFilterData(data.url,

我使用$q服务进行异步调用。我无法使用karma解决单元测试中的“then”和“defer”

下面是我的控制器代码

scope.filterUrls = [{url:'page1'}, {url: 'page2'}, {url:'page-error'}];

scope.bindFilters = function () {
angular.forEach(scope.filterUrls, function (data) {
    scope.getFilterData(data.url, '').then(function (result) {
      if (data.url === 'page1') {
        scope.moduleData.index = result.data;
      } else if (data.url === 'page2') {
        scope.moduleData.page2 = result.data;
      } 
     });
  });
}

scope.getFilterData = function (filterUrls, params) {
  // $q service object
  var deferred = q.defer();

  // regular ajax request
  http({
    method: 'GET',
    url: app.api.root + filterUrls,
    params: params
  })
      .success(function (result) {
        // promise resolve
        deferred.resolve(result);
      })
      .error(function (result) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
        deferred.reject('Erreur request : ' + result);
      });
  return deferred.promise;
};
测试规格:

it('should call getFilterData() in bindFilters()', function () {
    spyOn(scope, 'getFilterData');
    scope.bindFilters();
    expect(scope.getFilterData).toHaveBeenCalled();
  });
我收到一个名为“TypeError:无法读取未定义的'then'属性”的错误

如何使用karma为这两种方法编写单元测试

更新:

1.如何测试scope.getFilterData()的成功与错误

2.然后在scope.bindFilters()函数中执行函数


请帮助..

如果您只需要了解是否调用了
getFilterData
,请尝试通过伪造函数返回假承诺:

在jasmine 1.3中,我们可以使用
和callfake

it('should call getFilterData() in bindFilters()', function () {
    spyOn(scope, 'getFilterData').andCallFake(function(){//replace with a fake function
        var deferred = $q.defer(); //assume that you already inject $q service in beforeEach and save it as a variable.
        return deferred.promise; //returns a fake promise
    });
    scope.bindFilters();
    expect(scope.getFilterData).toHaveBeenCalled();
  });
在jasmine 2.0中,我们可以使用
和.callFake

另一种解决方案是使用
andReturnValue
$q.when()


使用jasmine 2.0,我们可以使用
和.returnValue来代替。

Khanh-TO:谢谢,但现在我得到了一个错误,因为“TypeError:undefined不是一个函数”。@Chandu:你注入了$q并将其保存在某处了吗?Khanh-TO:是的,我在每个之前都注入了$q并保存了它。@Chandu:看起来你当前的版本不支持andCallFake@Chandu:请尝试
和.callFake
it('should call getFilterData() in bindFilters()', function () {
        spyOn(scope, 'getFilterData').andReturnValue($q.when());
        scope.bindFilters();
        expect(scope.getFilterData).toHaveBeenCalled();
      });