【问题标题】:How to resolve $q.all promises in Jasmine unit tests?如何解决 Jasmine 单元测试中的 $q.all 承诺?
【发布时间】:2013-04-25 09:06:42
【问题描述】:

我的控制器有如下代码:

$q.all([qService.getData($scope.id), dService.getData(), qTService.get()])
.then(function (allData) {
  $scope.data1 = allData[0];
  $scope.data2 = allData[1];
  $scope.data3 = allData[2];
});

在我的单元测试中,我正在做这样的事情:

beforeEach(inject(function($rootScope, $q, $location){// and other dependencies... 
  qServiceSpy = spyOn(_qService, 'getData').andCallFake(function () {
    var data1 = {
      id: 1,
      sellingProperty: 1,
    };
    var d = $q.defer();
    d.resolve(data1);
    return d.promise;
  });

  dServiceSpy = spyOn(_dService, 'getData').andCallFake(function () {
    var data2 = [{ "id": "1", "anotherProp": 123 }];
    var d = $q.defer();
    d.resolve(data2);
    return d.promise;
  });
  qTServiceSpy = spyOn(_qTService, 'get').andCallFake(function () {
    var data3 = [{ id: 0, name: 'Rahul' }];
    var d = $q.defer();
    d.resolve(data3);
    return d.promise;
  });
  rootScope = $rootScope;
});

现在在我的测试中,我正在检查是否调用了服务,并且 data1、data2 未定义..

it('check if qService' got called, function() {
  expect(scope.data1).toBeUndefined();
  rootScope.$digest();
  expect(_quoteService.getQuote).toHaveBeenCalled();
});
it('check if "data1" is defined', function () {
  expect(scope.data1).toBeUndefined();
  rootScope.$digest();
  expect(scope.data1).toBeDefined();
});

我的问题是,在我将控制器中的个人服务调用替换为 q.all 并将测试中的 scope.$apply 替换为 rootScope.$digest 之前,这一切正常。使用 q.all 和 rootScope.$digest(也尝试使用 scope.$apply)两个测试都失败并出现错误:

达到 10 次 $digest() 迭代。中止!

如果我删除rootScope.$digest,那么承诺永远不会得到解决,并且测试失败说

预计未定义。

我应该如何使用q.all 对代码进行单元测试?

遇到this post

但这也无济于事,因为我已经在尝试使用$digest

【问题讨论】:

    标签: angularjs unit-testing jasmine karma-runner jasmine-jquery


    【解决方案1】:

    您可以尝试将$rootScope.$apply() 放入afterEach() 回调函数中。 Promise 在 Angular 中解析 $apply()

    afterEach(function(){
        rootScope.$apply();
    });
    

    【讨论】:

    • 如果您想知道记录在哪里:Differences between Kris Kowal's Q and $q & testing
    • $apply 通常会收到回调。我更喜欢scope.$digest(),它只消化当前作用域,所以性能更好。
    • afterEach 对我来说已经足够了。我刚刚测试了 afterEach() 函数内部的 Promise,它起作用了。泰人
    • 我个人经历了这种行为。我有 3 个承诺。在添加 afterEach...rootScope.$apply() 之前没有人工作。只有其中一个有效。
    • scope.digest 是否解决了所有的承诺?甚至嵌套的承诺?还是我需要多次调用它才能让代码继续
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    相关资源
    最近更新 更多