J'essaie d'ajouter des tests unitaires à mon application Angular 2. Dans l'un de mes composants, il y a un bouton avec un gestionnaire (click)
. Lorsque l'utilisateur clique sur le bouton, une fonction est définie dans le fichier de classe .ts
. Cette fonction imprime un message dans la fenêtre console.log indiquant que le bouton a été enfoncé. Mon code de test actuel teste l’impression du message console.log
:
describe('Component: ComponentToBeTested', () => {
var component: ComponentToBeTested;
beforeEach(() => {
component = new ComponentToBeTested();
spyOn(console, 'log');
});
it('should call onEditButtonClick() and print console.log', () => {
component.onEditButtonClick();
expect(console.log).toHaveBeenCalledWith('Edit button has been clicked!);
});
});
Cependant, cela ne fait que tester la classe du contrôleur, pas le HTML. Je ne veux pas simplement vérifier que la journalisation a lieu lorsque onEditButtonClick
est appelé; Je souhaite également tester que onEditButtonClick
est appelé lorsque l'utilisateur clique sur le bouton d'édition défini dans le fichier HTML du composant. Comment puis je faire ça?
Mon objectif est de vérifier si le 'onEditButtonClick' est invoqué lorsque l'utilisateur clique sur le bouton Modifier sans vérifier uniquement le fichier console.log en cours d'impression.
Vous devrez d'abord configurer le test à l'aide de la variable angulaire TestBed
. De cette façon, vous pouvez réellement saisir le bouton et cliquer dessus. Ce que vous allez faire est de configurer un module, comme vous le feriez avec un @NgModule
, juste pour l'environnement de test.
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
describe('', () => {
let fixture: ComponentFixture<TestComponent>;
let component: TestComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ ],
declarations: [ TestComponent ],
providers[ ]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
}));
});
Ensuite, vous devez espionner la méthode onEditButtonClick
, cliquer sur le bouton et vérifier que la méthode a été appelée.
it('should', async(() => {
spyOn(component, 'onEditButtonClick');
let button = fixture.debugElement.nativeElement.querySelector('button');
button.click();
fixture.whenStable().then(() => {
expect(component.onEditButtonClick).toHaveBeenCalled();
});
}));
Ici, nous devons exécuter un test async
car le clic du bouton contient la gestion des événements asynchrones et attendre que l'événement soit traité en appelant fixture.whenStable()
.
Voir également:
Les événements peuvent être testés à l'aide des fonctions async
fakeAsync
FOURNIES PAR '@angular/core/testing'
, CAR TOUS LES &EACUTE;V&EACUTE;NEMENTS DU NAVIGATEUR SONT ASYNCHRONES ET POUSS&EACUTE;S VERS LA BOUCLE/FILE D'ATTENTE D'&EACUTE;V&EACUTE;NEMENTS.
VOUS TROUVEREZ CI-DESSOUS UN EXEMPLE TR&EGRAVE;S SIMPLE DE TEST DE L'&EACUTE;V&EACUTE;NEMENT CLICK &AGRAVE; L'AIDE DE fakeAsync
.
LA FONCTION fakeAsync
ACTIVE UN STYLE DE CODAGE LIN&EACUTE;AIRE EN EX&EACUTE;CUTANT LE CORPS DE TEST DANS UNE ZONE DE TEST fakeAsync
SP&EACUTE;CIALE.
ICI, JE TESTE UNE M&EACUTE;THODE APPEL&EACUTE;E PAR L'&EACUTE;V&EACUTE;NEMENT CLICK.
it('should', fakeAsync( () => {
fixture.detectChanges();
spyOn(componentInstance, 'method name'); //method attached to the click.
let btn = fixture.debugElement.query(By.css('button'));
btn.triggerEventHandler('click', null);
tick(); // simulates the passage of time until all pending asynchronous activities finish
fixture.detectChanges();
expect(componentInstance.methodName).toHaveBeenCalled();
}));
VOICI CE QUE DOCS ANGULAIRES DOIS DIRE:
LE PRINCIPAL AVANTAGE DE FAKEASYNC PAR RAPPORT &AGRAVE; ASYNC EST QUE LE TEST SEMBLE &ECIRC;TRE SYNCHRONE. IL N'Y A PAS
then(...)
POUR PERTURBER LE FLUX DE CONTR&OCIRC;LE VISIBLE. LEfixture.whenStable
RETOURNANT LA PROMESSE EST PARTI, REMPLAC&EACUTE; PARtick()
_/IL SONT LIMITATIONS. PAR EXEMPLE, VOUS NE POUVEZ PAS PASSER D&RSQUO;APPEL XHR &AGRAVE; PARTIR DE
fakeAsync
J'utilise angulaire 6 . J'ai suivi la réponse de Mav55 et cela a fonctionné. Cependant, je voulais m'assurer que fixture.detectChanges();
était vraiment nécessaire, je l'ai donc retiré et cela fonctionnait toujours. Ensuite, j'ai supprimé tick();
pour voir si cela fonctionnait et cela a fonctionné. Enfin, j'ai retiré le test de l'emballage fakeAsync()
et, surprise, cela a fonctionné.
Alors j'ai fini avec ça:
it('should call onClick method', () => {
const onClickMock = spyOn(component, 'onClick');
fixture.debugElement.query(By.css('button')).triggerEventHandler('click', null);
expect(onClickMock).toHaveBeenCalled();
});
Et cela a bien fonctionné.