web-dev-qa-db-ja.com

ディレクティブをユニットテストする方法Angular 2?

問題:でディレクティブをテストしますAngular 2適切にコンパイルされること!

Angular 1)では、use$compile(angular.element(myElement) serviceを呼び出してから$scope.$digest()を呼び出すことができました。 Angularが<div my-attr-directive/>my-attr-directiveコンパイルします。

制約:

32
daniel.caspers

TestBedを使用したコンパイル済みディレクティブのテスト

次のディレクティブがあるとします。

@Directive({
  selector: '[my-directive]',
})
class MyDirective {
  public directiveProperty = 'hi!';
}

あなたがしなければならないことは、ディレクティブを使用するコンポーネントを作成することです(それはテスト目的のためだけである場合があります):

@Component({
  selector: 'my-test-component',
  template: ''
})
class TestComponent {}

次に、宣言されたモジュールを作成する必要があります。

describe('App', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        TestComponent,
        MyDirective
      ]
    });
  });

  // ...

});

コンポーネントにテンプレート(ディレクティブを含む)を追加できますが、テストでテンプレートを上書きすることで動的に処理できます。

it('should be able to test directive', async(() => {
  TestBed.overrideComponent(TestComponent, {
    set: {
      template: '<div my-directive></div>'
    }
  });

  // ...      

}));

これで、コンポーネントをコンパイルし、By.directiveを使用してクエリを実行できます。最後に、injectorを使用してディレクティブインスタンスを取得する可能性があります。

TestBed.compileComponents().then(() => {
  const fixture = TestBed.createComponent(TestComponent);
  const directiveEl = fixture.debugElement.query(By.directive(MyDirective));
  expect(directiveEl).not.toBeNull();

  const directiveInstance = directiveEl.injector.get(MyDirective);
  expect(directiveInstance.directiveProperty).toBe('hi!');
}); 

#古い答え:

ディレクティブをテストするには、それを使用して偽のコンポーネントを作成する必要があります。

@Component({
  selector: 'test-cmp',
  directives: [MyAttrDirective],
  template: ''
})
class TestComponent {}

コンポーネント自体にテンプレートを追加できますが、テストでテンプレートを上書きすることで動的に処理できます。

it('Should setup with conversation', inject([TestComponentBuilder], (testComponentBuilder: TestComponentBuilder) => {
    return testComponentBuilder
      .overrideTemplate(TestComponent, `<div my-attr-directive></div>`)
      .createAsync(TestComponent)
      .then((fixture: ComponentFixture<TestComponent>) => {
        fixture.detectChanges();
        const directiveEl = fixture.debugElement.query(By.css('[my-attr-directive]'));
        expect(directiveEl.nativeElement).toBeDefined();
      });
  }));

どのディレクティブがレンダリングされるかをテストすることはできますが、コンポーネントのようにディレクティブをテストする方法が見つかりませんでした(ディレクティブ用のTestComponentBuilderはありません)。

75

良い例を見つけるためにしばらく時間がかかりました。angular gitterチャンネルのいい人が、例のためにAngular Material Design 2リポジトリを見てくれました。ディレクティブテストの例を見つけることができます here 。これは、Material Design 2のツールヒントディレクティブのテストファイルです。コンポーネントの一部としてテストする必要があるようです。

3
Jusef