J'ai une configuration de projet Angular2 utilisant angular CLI. J'essaie de tester un composant de formulaire. Il a deux champs: email et mot de passe. Les deux sont required
. Il y a une connexion bouton de type submit
. Il n'est activé qu'après que l'utilisateur a fourni des entrées valides dans les deux champs.
<form (ngSubmit)="login()" #loginForm="ngForm">
<md-input-container class="md-block">
<input md-input [(ngModel)]="user.email" class="userEmail"
name="userEmail" type="email" placeholder="Email"
ngControl="userEmail"
required>
</md-input-container>
<br>
<md-input-container class="md-block">
<input md-input [(ngModel)]="user.password" class="userPassword"
name="userPassword" type="password" placeholder="Password"
ngControl="userPassword"
required>
</md-input-container>
<br>
<!--the button is enabled only after all form fields are valid-->
<button color="primary" md-button
type="submit" class='loginButton'
[disabled]="!loginForm.form.valid">
Login
</button>
Maintenant, je veux tester le bouton en utilisant le karma. J'ai parcouru les documents et j'ai pu tester l'entrée, en donnant une entrée aléatoire pendant le test et en la vérifiant:
//imports...
describe('LoginComponent (inline template)', () => {
let comp: LoginComponent;
let fixture: ComponentFixture<TmLoginComponent>;
let userEmail: HTMLInputElement;
let userPassword: HTMLInputElement;
let loginBtn: HTMLElement;
let title: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ], // declare the test component
imports: [ MaterialModule.forRoot(), FormsModule,
RouterTestingModule.withRoutes(
[{path: 'login', component: LoginComponent}, ])
],
providers: [{provide: UserAuthenticationService, useValue: uaServiceStub }, CookieService],
});
fixture = TestBed.createComponent(LoginComponent);
comp = fixture.componentInstance; //LoginComponent test instance
// query by CSS element selector
userEmail = fixture.debugElement.query(By.css('.userEmail')).nativeElement;
userPassword = fixture.debugElement.query(By.css('.userPassword')).nativeElement;
loginBtn = fixture.debugElement.query(By.css('.loginButton')).nativeElement;
//tests
//this test is successful
it('should check initial input', () => {
fixture.detectChanges();
expect(userEmail.value).toBe('')
});
//this test is successful
it('should check later input', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
userEmail.value = 'someValue';
userEmail.dispatchEvent(new Event('change'));
expect(userEmail.value).toBe('someValue');
});
}));
//EDITED: NEW TEST
it('should check loginBtn is disabled initially', () => {
fixture.detectChanges();
loginBtn = fixture.debugElement.query(By.css('.loginButton')).nativeElement;
fixture.whenStable().then(() => {
expect(loginBtn.disabled).toBe(true)
})
});
//this test fails. "Expected true to be false"
it('should check loginBtn is enabled after inputs check out', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
userEmail.value = '[email protected]';//valid
userEmail.dispatchEvent(new Event('change'));
userPassword.value = 'asdf';//vaild
userPassword.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(loginBtn.disabled).toBe(false)
})
}));
});
Je ne vois pas pourquoi le test échoue. Quelqu'un peut-il aider?
Si vous jetez un œil au code source de DefaultValueAccessor
:
Host: {'(input)': 'onChange($event.target.value)', '(blur)': 'onTouched()'},
vous pouvez remarquer que votre erreur principale est un nom d'événement incorrect.
Vous devez utiliser input
événement au lieu de change
it('should check loginBtn is enabled after inputs check out', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
userEmail.value = '[email protected]';
userEmail.dispatchEvent(new Event('input'));
userPassword.value = 'asdf';
userPassword.dispatchEvent(new Event('input'));
fixture.detectChanges();
expect(loginBtn.disabled).toBe(false)
});
}));