2

現在、コンポーネントの 1 つの単体テストを作成しています。特に、私はlogin(): void機能を持っています。単純化されたロジックは次のとおりです。

login(): void {
  this.showSpinner = true;
  this.userService.login(loginData)
    .subscribe(result => {
      this.showSpinner = false;
    }
  )
}

を呼び出す前にshowSpinnerプロパティが に設定されていることを確認するテストを書くのに苦労しています。trueuserService.login

これが私のテストです:

it('should display the spinner when the form is being saved',
  inject([TestComponentBuilder], fakeAsync((tcb: any) => {
    createComponent(tcb).then((fixture:ComponentFixture<any>) => {
      fixture.componentInstance.login();
      expect(fixture.componentInstance.showSpinner).toBe(true);
      tick();
    });
  })));
});

そして、このテストは失敗します。これは、.subscribeすぐに解決/実行されるためです (コンポーネントでコメントアウトしようとしたところthis.showSpinner = false、テストに合格しました)。

私のuserServiceモックでは、loginメソッドのモックに対して次のものがあります。

this.loginSpy = this.spy('login').andReturn(Observable.of(this));

はどこthisですかmockUserService

userServiceこのコンポーネントには正しく動作する他のテストがあるため、私はモックを作成し、特にloginメソッドをuserService正しく動作させていると確信しています。

また、スパイから戻ってテストObservable.of(this).delay(1)を呼び出してみました。tick(1)ただし、テストに合格することもあれば、次のようなエラーが表示されることもあるという点で、一貫性のない動作が発生します。

Error: 1 periodic timer(s) still in the queue.

に先行するロジックをテストするにはどうすればよい.subscribe()ですか?

4

1 に答える 1

0

さらに検討した結果、現在のコードが単一責任の原則に従っていないことに気付きました。この考えは、「テストしにくいコードをリファクタリングする」べきだと誰もが常に繰り返しているという事実から来ています。

それを念頭に置いて、呼び出しが行われる前に実行する必要のあるすべてのロジックをuserService.login、独自の別の関数に移動しました。これは本質的に次の結果になります。

login():void {
  this.userService.login(this.loginData)
    .subscribe(result => {
       this.showSpinner = false;
    });
}

formSubmit(): void {
  this.showSpinner = true;
  this.login();
}

このロジックは、テストがはるかに簡単になりました。

ただしlogin()、をテストしているときにメソッドにスパイを追加することを忘れformSubmit()ないでください。そうしないと、formSubmit()単に を呼び出すだけでlogin()、再び同期的に完了し、同じ問題が発生します。したがって、この機能に対する私の新しい最後のテストは次のとおりです。

it('should display the spinner when the form is being saved',
  inject([TestComponentBuilder], fakeAsync((tcb: any) => {
    createComponent(tcb).then((fixture:ComponentFixture<any>) => {
      var loginSpy = spyOn(fixture.componentInstance, 'login');
      fixture.componentInstance.formSubmit();
      expect(fixture.componentInstance.showSpinner).toBe(true);
    });
  })));
});
于 2016-05-21T20:32:10.760 に答える