【问题标题】:TypeError: Cannot read property 'then' of undefined angularjs-grunt testTypeError:无法读取未定义的 angularjs-grunt 测试的属性“then”
【发布时间】:2014-06-04 12:00:32
【问题描述】:

我正在使用 $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: Cannot read property 'then' of undefined”的错误。

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

更新:

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

2 .then 函数在 scope.bindFilters() 函数中。

请帮忙..

【问题讨论】:

    标签: angularjs unit-testing karma-runner q


    【解决方案1】:

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

    对于 jasmine 1.3,我们可以使用 andCallFake:

    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 中,我们可以改用 and.callFake

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

    it('should call getFilterData() in bindFilters()', function () {
            spyOn(scope, 'getFilterData').andReturnValue($q.when());
            scope.bindFilters();
            expect(scope.getFilterData).toHaveBeenCalled();
          });
    

    在 jasmine 2.0 中,我们可以改用 and.returnValue

    【讨论】:

    • Khanh TO:谢谢,但现在我收到错误消息“TypeError: undefined is not a function”。
    • @Chandu:你注入 $q 并保存在某个地方了吗?
    • Khanh TO:是的,我在 beforeEach 上注入了 $q 并保存了它。
    • @Chandu:你现在的版本好像不支持andCallFake。 github.com/karma-runner/karma-jasmine/issues/24
    • @Chandu:请尝试and.callFake
    猜你喜欢
    • 2015-03-28
    • 2019-08-19
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多