Karma Angular 单元测试如何创建未解决的承诺并在单个测试中解决它,以检查 then 中的代码是否仅在解决后运行

问题描述 投票:0回答:1

我有承诺功能

waitUntilIsReady

  (...)

  private inProgressSubject = new BehaviorSubject<boolean>(true)

  waitUntilIsReady(): Promise<void> {
    const untilInProgress = new Subject<void>()

    return new Promise((resolve) => {
      this.inProgress.pipe(takeUntil(untilInProgress)).subscribe((inProgress) => {
        if (inProgress) {
          return
        }

        untilInProgress.next()
        untilInProgress.complete()
        resolve()
      })
    })
  }

  (...)

我使用它来确保仅在一切准备就绪时才运行某些特定代码(在 init 上)。

  ngOnInit(): void {
    this.service.waitUntilUserIsReady().then(() => {
      this.otherService.doSomething()
    })
  }

第一个问题是:如何编写测试来检查对

doSomething()
的调用是否仅在 Promise 解决之后而不是之前运行?

从上面的问题中出现了一个主要问题:如何创建 Promise,而不需要在测试一段时间后解决它?

类似于在测试中创建

Observable Subject
并调用
next

const fakeSubject = new Subject<Message>()

describe('Xyz', () => {
  let spectator: Spectator<Xyz>
  const createComponent = createComponentFactory({
    component: Xyz,
    providers: [
      MockProvider(Service, {
        someObservableToChangeFlag: fakeSubject.asObservable()
      }),
      MockProvider(OtherService, {
        doSomething: jasmine.createSpy()
      }),
    ],
  })

  beforeEach(() => (spectator = createComponent()))

  it('should something', fakeAsync(() => {
    const otherService = spectator.inject(OtherService)

    expect(otherService.doSomething).not.toHaveBeenCalled()

    someObservableToChangeFlag.next()
    tick()

    expect(otherService.doSomething).toHaveBeenCalled()
  }))

我只知道如何测试它是否运行,而不检查是否在 Promise 函数中:

escribe('Xyz', () => {
  let spectator: Spectator<Xyz>
  const createComponent = createComponentFactory({
    component: Xyz,
    providers: [
      MockProvider(Service, {
        waitUntilIsReady: jasmine.createSpy().and.resolveTo(),
      }),
      MockProvider(OtherService, {
        doSomething: jasmine.createSpy()
      }),
    ],
  })

  beforeEach(fakeAsync(() => (spectator = createComponent())))

  it('should "Do something" on promise', () => { // <- This test is not preventing from simply moving logic out side of Promise
    const otherService = spectator.inject(OtherService)

    expect(otherService.doSomething).toHaveBeenCalled()
  })

  it('should "Do something" on promise', fakeAsync(() => { // <- Something "like" what I want
    const otherService = spectator.inject(OtherService)

    // Assert if nothing happened
    expect(otherService.doSomething).not.toHaveBeenCalled()
    
    // Trigger Promise
    ? promise.trigger() ?
    tick()

    // Assert if logic inside of Promise was called
    expect(otherService.doSomething).toHaveBeenCalled()
  }))

我试过了

waitUntilIsReady: jasmine.createSpy().and.returnValue(Observable.of().pipe(delay(500)).toPromise()),

但是

toPromise
已弃用。

angular typescript karma-jasmine
1个回答
0
投票

您可以使用以下内容:

jasmine.createSpy().and.returnValue(Promise.resolve());

或者更简单...

jasmine.createSpy().and.resolveTo();

有关更多详细信息,请参阅

Jasmine
文档:https://jasmine.github.io/api/edge/SpyStrategy.html

© www.soinside.com 2019 - 2024. All rights reserved.