我有promise 功能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 解决之后运行,而不是在此之前运行?
从上面的问题中产生了一个主要的问题:How to create Promise without resolving it to be resolved after some time in test?
这类似于在测试中创建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
是不受欢迎的.