web-dev-qa-db-ja.com

Angular2単体テスト:コンポーネントのコンストラクターのテスト

すべてがタイトルにあります:コンポーネントのコンストラクタで何が行われるかをテストするにはどうすればよいですか?

参考までに、設定が必要なサービスを利用していますが、コンストラクタで呼び出す2つのメソッドが正しく呼び出されるかどうかを確認したいと思います。

私のコンポーネントのコンストラクタ:

constructor(
  public router: Router,
  private profilService: ProfileService,
  private dragula: DragulaService,
  private alerter: AlertService
) {
  dragula.drag.subscribe((value) => {
    this.onDrag(value);
  });
  dragula.dragend.subscribe((value) => {
    this.onDragend(value);
  });
}
10
user4676340

DIシステムを使用して偽のサービスを注入します。つまり、次のようなテストを作成することになります。

describe('your component', () => {
  let fixture: ComponentFixture<YourComponent>;
  let fakeService;
  let dragSubject = new ReplaySubject(1);
  ...

  beforeEach(async(() => {
    fakeService = { 
      drag: dragSubject.asObservable(),
      ... 
    };

    TestBed.configureTestingModule({
      declarations: [YourComponent, ...],
      providers: [
        { provide: DragulaService, useValue: fakeService }, 
        ...
      ],
    });
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(YourComponent);
    fixture.detectChanges();
  });

  it('should do something when a drag event occurs', () => {
    dragSubject.next({ ... });
    fixture.detectChanges();
    ...
  });
});

これにより、件名で.nextを呼び出すことにより、いつでも「ドラッグイベント」をトリガーできます。これにより、偽のサービスのフィールドのサブスクライバーが呼び出されます。次に、そこから期待する結果についてアサーションを作成できます。

constructorを自分で呼び出す必要がないことに注意してください。このメソッドは、DIシステムがコンポーネントをインスタンス化するとき、つまりTestBed.createComponentが呼び出されるときに呼び出されます。

コンポーネントメソッド(例:this.onDrag)をスパイしないことをお勧めしますが、それらが呼び出されることを確認してください。結果としてこれらのメソッドが実行する必要があることをテストします。これにより、特定の実装の変更に対してテストがより堅牢になります(これについてはブログで少し書きました: http://blog.jonrshar.pe/2017/Apr/16/async-angular-tests.html )。

15
jonrsharpe

コンストラクター関数内で何かをテストする簡単な方法は、コンポーネントインスタンスを作成してからテストすることです。

_it('should call initializer function in constructor', () => {
  TestBed.createComponent(HomeComponent); // this is the trigger of constructor method
 expect(sideNavService.initialize).toHaveBeenCalled(); // sample jasmine spy based test case
});
_

コンストラクタとngOnInitを区別したい場合は、fixture.detectChanges()内でbeforeEach()を呼び出さないでください。代わりに、必要なときはいつでも手動で呼び出します。

OPは「コンストラクターで呼び出す2つのメソッドが正しく呼び出されるかどうかを確認したい」と述べています。私にはもっと良いアプローチがあります。

単体テストを作成します。このためにテストベッドを使用する必要はありません。テストが大幅に遅くなります。モックを手動でインスタンス化します。興味のあるメソッドにスパイを設定し、インスタンス化したスタブを使用してコンポーネントコンストラクターを手動で呼び出し、スパイを設定します。次に、スパイされたメソッドが正しく呼び出されたかどうかをテストします。

重要なのは、元のサービスクラスからスタブを拡張することです。 jasmine.createSpyObjは、angular Routerのようなクラスをモックするのに役立ちます。

0
aycanadal