[英]Unit testing a BehaviorSubject in a service
我正在做一个玩具项目来学习 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);
}
// ...
}
和一个组件上的监听器,它使用模板中的异步 pipe 订阅 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
function 时,组件中的remainingSeconds$ observable 也能得到正确的值。 特别是,如果服务中的“remainingSeconds”值未定义,我想确保剩余的Seconds$ observable 获得更新的未定义值,从而隐藏适当的UI 元素。
我在测试中遇到的问题(代码如下)是,当我从组件调用service.setTimer(undefined)
时,我得到的是 BehaviorSubject 的初始值,而不是我想要的undefined
值(这使测试无用)。
it(`shouldn't render the timer component if the seconds value is unset`, async(() => {
component.remainingSeconds$
.subscribe(
seconds => {
expect(seconds).toEqual(undefined);
fixture.detectChanges();
const timerContainerDom: DebugElement = fixture.debugElement;
const regularTimerComponent = timerContainerDom.query(By.directive(AppComponent));
expect(regularTimerComponent).toBeFalsy();
}
);
timerService.setTimer(undefined);
}));
我正在添加一个 stackblitz 链接,但遗憾的是我无法在那里运行 npm 测试。 希望它能给我一些关于我想要完成的事情的基本想法。
您可以通过以下方式快速解决此问题:
component.remainingSeconds$.pipe(skip(1)).subscribe(...)
尝试
TestBed.configureTestingModule({
declarations: [
AppComponent
],
providers: [
TimerService
]
}).compileComponents();
并删除 TestBed.inject
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.