I have a form that has an input and I have a button that needs to be enabled only when the form data was changed. I am using a pristine check and it all works functionally in the browser but I am having trouble to test it. No matter what I do the pristine check is always true no matter how many times I set the values. Any idea what I am doing wrong?
The HTML has 2 inputs with labels and a button
<form (ngSubmit)="login()"
[formGroup]="form">
<label>Email</label>
<input type="email" formControlName="email" name="email">
<label>Password</label>
<input type="password" formControlName="password">
<button type="submit">Login</button>
</form>
My typescript file
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
export class User {
constructor(public email: string,
public password: string) {
}
}
@Component({
selector: 'app-login-component',
templateUrl: './login-component.component.html',
styleUrls: ['./login-component.component.scss']
})
export class LoginComponentComponent implements OnInit {
@Output() loggedIn = new EventEmitter<User>();
form: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.form = this.fb.group({
email: ['', [Validators.required, Validators.pattern("[^ @]*@[^ @]*")]],
password: ['', [Validators.required, Validators.minLength(8)]],
});
}
login() {
console.log(`Login ${this.form.value}`);
if (this.form.valid) {
this.loggedIn.emit(
new User(
this.form.value.email,
this.form.value.password
)
);
}
}
}
And the 2 tests. I have tried with asych testing and without. I also tried setting the value of the native element and on the form. But in both cases the pristine check is always true. Any idea what I am doing wrong?
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginComponentComponent} from './login-component.component';
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {By} from "@angular/platform-browser";
describe('Component: Login', () => {
let component: LoginComponentComponent;
let fixture: ComponentFixture<LoginComponentComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule, FormsModule],
declarations: [LoginComponentComponent]
});
fixture = TestBed.createComponent(LoginComponentComponent);
component = fixture.componentInstance;
component.ngOnInit();
});
it('Tried WIHTOUT async function', () => {
expect(component.form.pristine).toBeTrue(); //Should not be in a modified state when it starts
fixture.detectChanges();
const inputElement = fixture.debugElement.query(By.css('input[name="email"]')).nativeElement;
//Try to set the control itself and the form
component.form.controls.email.setValue("2")
inputElement.value = '2';
//Detect changes and wait to be stable
fixture.detectChanges();
expect(inputElement.value).toEqual("2"); //Test that the value has infact change
expect(component.form.pristine).toBeFalse(); //This fails
});
it('Tried using async function', async(() => {
expect(component.form.pristine).toBeTrue(); //Should not be in a modified state when it starts
fixture.detectChanges();
const inputElement = fixture.debugElement.query(By.css('input[name="email"]')).nativeElement;
//Try to set the control itself and the form
component.form.controls.email.setValue("2")
inputElement.value = '2';
//Detect changes and wait to be stable
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(inputElement.value).toEqual("2"); //Test that the value has infact change
expect(component.form.pristine).toBeFalse(); //This fails
});
}));
});
question from:
https://stackoverflow.com/questions/65645144/testing-angular-component-form-for-pristine-is-not-working 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…