用茉莉花

时间:2016-12-17 07:16:50

标签: angularjs unit-testing jasmine angular-promise

我的控制器中有以下功能:

function putActivities () {
    var promises = [];
    view.activities.forEach(function (activity) {
        promises.push(API.putActivities({activity: activity}).$promise);
    });
    $q.all(promises).then(function () {
        view.finished = true;
    });
}

其中API是$资源。此方法由以下代码段进行测试:

describe('putActivities', function() {
    beforeEach(function() {
        view.activities = ['hello'];
        spyOn(API, 'putActivities').and.callFake(function () {
            return {
                $promise: q(function () {})
            }
        });
    });
    it('view is finished after putting activities', function() {
        view.putActivities();
        expect(view.finished).toEqual(true);
    });
});

由于某种原因,$ q.all永远不会解析,view.finished永远不会设置为true。有谁知道为什么会发生这种情况以及我如何解决它?

1 个答案:

答案 0 :(得分:1)

间谍返回的假承诺需要手动解决(或拒绝)。

不确定间谍中的q函数是做什么的,但我会在示例中使用Angular的$q

beforeEach(function() {

  view.activities = ['hello'];
  mockedPromises = [];

  spyOn(API, 'putActivities').and.callFake(function() {

    var defer = $q.defer();
    mockedPromises.push(defer);

    return {
      $promise: defer.promise
    };
  });
});

现在您可以访问测试中的promise,并可以解析或拒绝它们,具体取决于您要测试的场景:

it('view is finished after putting activities', function() {

  view.putActivities();

  mockedPromises.forEach(function(promise) {
    promise.resolve();
  });

  $rootScope.$apply();

  expect(view.finished).toEqual(true);
});

请注意,在测试promises时(至少使用$q服务),promises的解析与摘要周期相关联,这意味着then函数仅在摘要具有后才会被调用运行

测试时,您需要手动触发摘要周期(这样您可以更好地控制流量)。这就是$rootScope.$apply()的作用。