Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular test – enable button when form becomes valid

I have such a form in my App, with a required field, and a button that becomes enabled once the field is not empty.

upload.component.html

<form [formGroup]="uploadForm" (ngSubmit)="Submit()">
                    <mat-form-field class="full-width" appearance="outline">
                      <mat-label translate>enter-name</mat-label>
                      <input matInput formControlName="name">
                    </mat-form-field>
<button mat-raised-button  [disabled]="!uploadForm.valid">Send</button>
</form>

And upload.component.ts:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  ngOnInit() {
    this.uploadForm = new FormGroup({
       'name': new FormControl('', Validators.required),
      );
   }

I want to test this case.

Trying this, upload.component.spec.ts:

   it('should be ok', waitForAsync(() => {
                let fixture = TestBed.createComponent(DashboardComponent);
                fixture.detectChanges();
                fixture.whenStable().then(() => {
                  let input = fixture.debugElement.nativeElement.querySelector('[matInput]');
                  input.value = 'someValue';
                  input.dispatchEvent(new Event('input'));
     expect(fixture.debugElement.nativeElement.querySelector('button').disabled).toBeFalsy();
                    });
        }));

Doesn’t work.

Can anyone please help me with the syntax?

Thanks!

>Solution :

I think you’re missing a fixture.detectChanges() since the model changed. Try this:

it('should be ok', waitForAsync(() => {
                let fixture = TestBed.createComponent(DashboardComponent);
                fixture.detectChanges();
                fixture.whenStable().then(() => {
                  let input = fixture.debugElement.nativeElement.querySelector('[matInput]');
                  input.value = 'someValue';
                  input.dispatchEvent(new Event('input'));
                  // !! need another fixture.whenStable since some aspects of a form are asynchronous
                   fixture.whenStable().then(() => {
                    // !! add a fixture.detectChanges() since the model changed
                   fixture.detectChanges();
                   
expect(fixture.debugElement.nativeElement.querySelector('button').disabled).toBeFalsy();
                });
                  
             });
        }));

That being said, the good thing about ReactiveForms is that you don’t need to mess around with the view. You can just play with the form and get what you want.

Something like this:

it('should be ok', () => {
   // !! first fixture.detectChanges() calls ngOnInit
   fixture.detectChanges();
   // !! change the model directly
   component.uploadForm.get('name').setValue('someValue');
   // !! update the view with fixture.detectChanges()
   fixture.detectChanges();
   expect(fixture.debugElement.nativeElement.querySelector('button').disabled).toBeFalsy();
  
});

I think a test like that ^ is much easier to write.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading