私のAngularサービスには、特定の条件が満たされるまでスピナーを表示するためにポーリングを実行するコードがいくつかあります:
@Inject({…})
export class SomeService {
backendCall(): Observable<SomeStatusWrapper> {
return this.http.get(…)
}
isDocumentReady(): Observable<boolean> {
const hasFinished = new Subject<boolean>()
return interval(1000).pipe(
switchMap(idx => of(idx).pipe(delay(idx*250))), // Increment delay between retries
switchMap(() => this.backendCall()),
map(({status}) => status === 'Done'),
tap(done => done?hasFinished.next(done) : undefined),
distinctUntilChanged(),
takeUntil(hasFinished),
endWith(true)
)
}
}
さて、これに単体テストを追加したいと思います。Jasmine のビー玉を使用していますが、フレームがいくつあるかわからないため、単体テストを機能させることができません。
大理石の構文で「間隔」をどのように表現しますか? cold('1000ms (a|)',{a:true})
1000ミリ秒待機し、「true」を発行して同時に完了するようなことができることを私は知っています。
このテストはパスすると思っていましたが、失敗しました。
it('should emit false after 1000ms', () => {
const service = TestBed.inject(service) // already mocked backendCall to return a status != 'Done'
expect(service.isDocumentReady()).toBeObservable(cold('1000ms f', {f: false}))
})
よりシンプルなバージョン
このテストに合格するには、ジャスミン ビー玉をどのように記述すればよいですか?
describe('', () => {
it('should pass', () => {
const stream$ = interval(1000).pipe(
switchMap(val => of(val).pipe(delay(250*val))),
mapTo(false)
)
expect(stream$).toBeObservable(cold(???, {f:false}))
})
})