我正在研究一个玩具项目,以学习Angular中的单元测试(用Jest代替了Karma)。我见过类似的问题,但所有问题对订阅的处理方式都不一样,因此我无法获得确切的答案来为我工作。
TL; DR:我正在尝试测试BehaviorSubject,但是它不是我期望的值,而是向我发送的初始值。我了解测试中订阅的顺序很重要,但是我还无法确定正确的顺序。
我在服务中有一个BehaviorSubject:
export class SomeService {
// ...
remainingSeconds: number;
private _seconds: Subject<number> = new BehaviorSubject(RegularTimerSeconds.WORK_TIME);
public readonly seconds$: Observable<number> = this._seconds.asObservable();
setTimer(seconds: number) {
this.remainingSeconds = seconds;
this._seconds.next(this.remainingSeconds);
}
// ...
}
和组件上的侦听器,该组件使用模板中的异步管道订阅了Observable
export class SomeComponent implements OnInit, OnDestroy {
// ...
remainingSeconds$ = this.timer.seconds$.pipe(tap(seconds => console.log(`remainingSeconds$: ${seconds}`)));
constructor(public timer: TimerService) {}
}
订阅在模板中进行如下
<ng-container *ngIf="{
remainingSeconds: remainingSeconds$ | async,
currentState: currentState$ | async,
informationText: informationText$ | async,
doneCounter: doneCounter$ | async
} as data">
<!-- ... -->
<div class="regular-timer-container" *ngIf="data.remainingSeconds !== undefined">
<p>Remaining seconds: {{ data.remainingSeconds }}</p>
</div>
</ng-container>
我想测试一下,当调用服务中的setTimer
函数时,组件中可观察到的剩余Seconds $是否也获得了正确的值。尤其是,如果未定义服务中的“ remainingSeconds”值,则我想确保ObservableSeconds $ observable获取更新后的未定义值,并因此隐藏了适当的UI元素。
测试遇到的问题(代码如下)是,当我从组件调用service.setTimer(undefined)
时,我得到的是BehaviorSubject的初始值,而不是{{1 }}我想要的值(这使测试无用)。
undefined
我要添加a stackblitz link,但是很遗憾,我无法在该处运行npm test。希望它将对我要完成的工作给出一些基本的想法。
答案 0 :(得分:1)
您可以使用以下方法快速解决此问题:
component.remainingSeconds$.pipe(skip(1)).subscribe(...)
答案 1 :(得分:0)
尝试
TestBed.configureTestingModule({
declarations: [
AppComponent
],
providers: [
TimerService
]
}).compileComponents();
并删除TestBed.inject