1

I am facing an issue to write an unit test case in jasmine for my angular application. Have a reactive form and trying to reset a particular form control from a button click. Even though the scenario should be simple enough to test, it seems that I am missing something here.

Below is the code snippet from the app.

app.component.html:

<form [formGroup]="userForm" novalidate (ngSubmit)="onSubmit()">
  <div>
    <input
      type="text"
      id="fNameFld"
      name="fName"
      formControlName="fName"
      placeholder="First Name"
    />
    <button (click)="clearField('fName')" id="clrFName">
      Clear First Name
    </button>
  </div>

  <div>
    <input
      type="text"
      id="lNameFld"
      name="lName"
      formControlName="lName"
      placeholder="Last Name"
    />
    <button (click)="clearField('lName')" id="clrLName">Clear Last Name</button>
  </div>

  <div>
    <button type="submit">Submit</button>
  </div>
</form>

app.component.ts

import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;
  userForm: FormGroup;

  constructor(private readonly fb: FormBuilder) {}

  ngOnInit() {
    this.userForm = this.fb.group({
      fName: this.fb.control(null),
      lName: this.fb.control(null),
    });
  }

  onSubmit() {
    console.log('Submitted Data', this.userForm.value);
  }

  clearField(controlName: string) {
    this.userForm.get(controlName).reset();
  }
}

Unit test code

it('should clear fName control when the "Clear First Name" button is clicked', () => { 
    const spy = spyOn(component, 'clearField');
    const clearBtn = fixture.debugElement.query(By.css("button#clrFName"));
    const form = component.userForm;
    
    form.patchValue({
      'fName': 'John,
      'lName': 'Doe'
    });
    
    clearBtn.nativeElement.click();
    fixture.detectChanges();
    expect(spy).toHaveBeenCalledTimes(1);  // passes
    expect(spy).toHaveBeenCalledWith('fName');  // passes
    expect(form.get('fName').value).toBeNull();  // fails: Expected 'John' to be null.
  });

Angular: 10.0.14

Angular CLI: 10.0.8

StackBlitz: https://angular-ivy-fc6rik.stackblitz.io

1 Answer 1

2

seems like you mocked clearField. Add this to actually execute its content when you mock it:

const spy = spyOn(component, 'clearField').and.callThrough();

So everytime clearField is called, it will trigger the spy (so you know if it has been called), and will execute its content .

Sign up to request clarification or add additional context in comments.

1 Comment

you are a Rockstar!! your solution worked for me, the unit test case is now passing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.