使用 Angular Promise 的 Jasmine 测试未使用 TypeScript 解析

Jasmine Testing with Angular Promise not resolving with TypeScript

我有一个相当简单的测试,它针对 Angular promise,我在 beforeEach 函数中解决了这个问题,但是我的代码中的 then 永远不会触发,我看不到我要做什么失踪了。这些都是用 TypeScript 写的,但是这对问题没有任何影响。

这是我的测试

describe('Refresh->', () => {

  var controller = new Directives.Reporting.ReportDirectiveController($scope, $q, $location);
  var called = false;
  var defer: any;

  beforeEach((done) => {
    controller.drillReport = (drillReport: Models.drillReport): ng.IPromise<Models.drillData> => {
      defer = $q.defer();
      called = true;
      defer.resolve({});
      return defer.promise;
    };
    spyOn(controller, 'processResults');
    controller.refresh();
    done();
  });

  it('Calls DrillReport', () => {
    expect(called).toBeTruthy();
  });

  it('Calls ProcessResults', () => {
    expect(controller.processResults).toHaveBeenCalled();
  });
});

控制器中的 Refresh 方法如下所示:

refresh() {
  this.drillReport({ drillReport: drillReport })
    .then((results: Models.drillData) => {
      parent.processResults(results, parent.availableDrills, this.columns, this.gridOptions, undefined, undefined);
    });
}

您缺少的是您需要使用 $scope$rootScope 的权限,以便您可以调用并强制执行摘要循环...

$scope.$digest();

之所以需要这样做是因为在摘要循环期间处理了已解决和已拒绝的承诺。因此,当您在模拟中解决承诺时,实际的承诺回调不会被调用。

跟进@Brocco 所说的内容,您的代码在处理 promise 之前调用 done()。

您需要一种方法让您的测试代码知道 parent.processResults() 已被调用。

我建议你刷新 return 一个将在 parent.processResults() 之后解决的承诺,并在你的测试代码中添加 controller.refresh().finally(() => { done(); });