使用 Angular Promise 进行 Jasmine 测试无法使用 TypeScript 解决

Posted

技术标签:

【中文标题】使用 Angular Promise 进行 Jasmine 测试无法使用 TypeScript 解决【英文标题】:Jasmine Testing with Angular Promise not resolving with TypeScript 【发布时间】:2016-06-01 04:10:49 【问题描述】:

我有一个针对 Angular 承诺的相当简单的测试,我在 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);
    );

【问题讨论】:

【参考方案1】:

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

$scope.$digest();

需要这样做的原因是在摘要循环期间处理已解决和拒绝的承诺。因此,当您在模拟中解决承诺时,并没有调用实际的承诺回调。

【讨论】:

谢谢。我知道,但忘记了。【参考方案2】:

按照@Brocco 所说的,您的代码在处理承诺之前调用了 done()。

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

我建议您刷新返回一个将在parent.processResults() 之后解决的承诺,并在您的测试代码中添加controller.refresh().finally(() =&gt; done(); );

【讨论】:

以上是关于使用 Angular Promise 进行 Jasmine 测试无法使用 TypeScript 解决的主要内容,如果未能解决你的问题,请参考以下文章

Angular2中Http的Promise vs Observable? [复制]

在Angular 2中拒绝Promise时未处理的Promise拒绝[重复]

Promise.all 的 then() 函数在 Promise 完成之前执行 - Ionic/Angular

在 Angular 中,如何在使用 async/await 时处理 Promise 拒绝

Angular 2:将 Observable 转换为 Promise

RxJS Observables 的 Promise.all 行为?