Problème: J'aimerais pouvoir tester une directive une unité en Angular 2 pour être sûr qu'il compile correctement.
Dans Angular 1, il était possible d'utiliser $compile(angular.element(myElement)
service et d'appeler $scope.$digest()
après cela. Je veux spécifiquement pouvoir le faire dans des tests unitaires afin Je pourrais tester cela quand Angular finit par courir à travers <div my-attr-directive/>
dans le code qui my-attr-directive
compile.
Contraintes:
Disons que vous avez une directive suivante:
@Directive({
selector: '[my-directive]',
})
class MyDirective {
public directiveProperty = 'hi!';
}
Ce que vous devez faire, c'est créer un composant qui utilise la directive (cela peut être juste à des fins de test):
@Component({
selector: 'my-test-component',
template: ''
})
class TestComponent {}
Maintenant, vous devez créer un module qui les a déclarés:
describe('App', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
MyDirective
]
});
});
// ...
});
Vous pouvez ajouter le modèle (qui contient une directive) au composant, mais il peut être géré dynamiquement en écrasant le modèle dans test:
it('should be able to test directive', async(() => {
TestBed.overrideComponent(TestComponent, {
set: {
template: '<div my-directive></div>'
}
});
// ...
}));
Vous pouvez maintenant essayer de compiler le composant et l'interroger à l'aide de By.directive
. À la toute fin, il est possible d'obtenir une instance de directive en utilisant le 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!');
});
Pour tester une directive, vous devez créer un faux composant avec elle:
@Component({
selector: 'test-cmp',
directives: [MyAttrDirective],
template: ''
})
class TestComponent {}
Vous pouvez ajouter le modèle dans le composant lui-même, mais il peut être géré dynamiquement en écrasant le modèle dans test:
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();
});
}));
Notez que vous êtes en mesure de tester ce que rend la directive mais je n'ai pas trouvé le moyen de tester une directive de la même façon que les composants (il n'y a pas de TestComponentBuilder pour les directives).
Il m'a fallu du temps pour trouver un bon exemple, une bonne personne sur angular gitter channel m'a indiqué de regarder le Angular Material Design 2 repository pour des exemples. Vous peut trouver un exemple de test de directive ici . Il s'agit du fichier de test pour la directive info-bulle de Material Design 2. Il semble que vous devez le tester en tant que partie d'un composant.