【问题标题】:How do I properly test using a mocked service that returns a Promise?如何使用返回 Promise 的模拟服务进行正确测试?
【发布时间】:2020-04-26 19:46:33
【问题描述】:

我是 Angular 的新手,我仍在尝试弄清楚它是如何工作的。我目前无法测试依赖于返回Promise 的服务的组件。我正在测试的函数结构如下:

success: boolean;    

borrowBook() {
  this.bookService.borrow(this.selectedBook.id)
    .then(() => {
      this.success = true;
    })
    .catch((error: BorrowingError) => {
      this.success = false;
    });
}

现在,我不确定上面的代码是否被认为是惯用的,但这就是我编写代码的方式。在我的单元测试中,我使用jasmine.createSpyObj 函数模拟了bookService,并将存根定义如下:

mockBookService.borrow.and.returnValue(Promise.resolve(testResult));

但是,我的测试失败了,说 component.success 是未定义的,而我期望它是真实的。我的测试编程如下:

it('test', async(() => {
  mockBookService.borrow.and.returnValue(Promise.resolve(testResult));
  //setup pre-conditions here...
  component.borrowBook(();

  expect(component.success).toBeTruthy();
}));

我的印象是,甚至在相应地处理 Promise 之前就已经检查了期望。

【问题讨论】:

    标签: javascript angular unit-testing rxjs jasmine


    【解决方案1】:

    我偶然发现了这个article about testing asynchronous code in Angular,它指出flushMicrotasks 函数可用于在检查期望之前运行所有异步组件。这仅通过fakeAsync 创建的假区域提供,因此在我的代码中我使用了它而不是仅使用async

    it('test', fakeAsync(() => { //used fakeAsync instead
      mockBookService.borrow.and.returnValue(Promise.resolve(testResult));
      //setup pre-conditions here...
      component.borrowBook(();
    
      flushMicrotasks(); //added this before checking expectations
      expect(component.success).toBeTruthy();
    }));
    

    【讨论】:

    • 我觉得你也可以这样做:async(() => { comp.borrowBook(); fixture.whenStable(() => expect(...)) })
    • @AndreiGătej 我试过了,但由于某种原因它对拒绝测试用例不起作用。
    • 啊,我的错。我滥用了语法。应该是:fixture.whenStable().then(() => { expect(...) })
    • 不用担心。在尝试这种flushMicrotask 方法之前,我实际上尝试过使用正确的语法,但它仍然不适用于拒绝测试用例。
    • 有趣。感谢分享!我将对此进行调查。
    猜你喜欢
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 2021-01-18
    • 2014-06-21
    相关资源
    最近更新 更多