Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 对服务中的行为主体进行单元测试_Angular_Unit Testing_Rxjs - Fatal编程技术网

Angular 对服务中的行为主体进行单元测试

Angular 对服务中的行为主体进行单元测试,angular,unit-testing,rxjs,Angular,Unit Testing,Rxjs,我正在做一个玩具项目,学习用玩笑代替因果报应的单元测试。我见过类似的问题,但它们处理订阅的方式都不同,所以我无法得到适合我的确切答案 TL;DR:我试图测试一个行为主体,但它不是我期望的值,而是向我发送它的初始值。我了解测试事项中订阅的顺序,但我还不能确定正确的顺序 我在服务中有一个行为主体: export class SomeService { // ... remainingSeconds: number; private _seconds: Subject<number

我正在做一个玩具项目,学习用玩笑代替因果报应的单元测试。我见过类似的问题,但它们处理订阅的方式都不同,所以我无法得到适合我的确切答案

TL;DR:我试图测试一个行为主体,但它不是我期望的值,而是向我发送它的初始值。我了解测试事项中订阅的顺序,但我还不能确定正确的顺序

我在服务中有一个行为主体:

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);
  }

  // ...
}
订阅在模板中发生,如下所示

<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>
我正在添加,但遗憾的是我无法在上面运行npm测试。希望它能给我一些基本的想法,让我知道我要完成什么。

试试看

TestBed.configureTestingModule({
        declarations: [
          AppComponent
        ],
        providers: [
          TimerService
        ]
      }).compileComponents();

并移除测试床。注入

您可以通过以下方法快速解决此问题:

component.remainingSeconds$.pipeskip1.subscribe。。。
感谢您的回答:在测试中,我使用了timerService的一个实例。您建议在何处以及如何实例化它?无需实例化它,只需将其添加到提供程序数组中即可。然后从testbed.get获取服务实例。实际上,我之所以使用.inject是因为您尝试过component.remainingSeconds$.pipeskip1.subscribe@AndreiGătej感谢您的回复-我没有用过。理论上和实践上它都很好,因为它跳过了BehaviorSubject的初始值,这就解决了我的问题。同时,我想知道测试行为主体是否有一个通用的良好实践。如果你能将此作为答案发布,我将选择它作为好答案我不知道“一刀切”的解决方案,但在你的情况下,我要做的是将任务分开,问自己:我想测试什么?例如,如果要测试可观察对象在某些事件后是否发出正确的值,则可能需要对此使用大理石测试。如果您想测试某些元素是否正确地出现在DOM中,我不会将eventse.g的真实源作为一个主题,而是一个模拟的可观察对象,它只会发出一些值,让我可以专注于视图测试。我已经添加了答案。谢谢
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);
}));
TestBed.configureTestingModule({
        declarations: [
          AppComponent
        ],
        providers: [
          TimerService
        ]
      }).compileComponents();