angularunit-testingangular-reactive-formsangular-template-form

Template driven input and reactive input not working the same in component DOM test


I use template driven input and can not get its value in unit test unlike of reactive input.

Here are two same components one implemented with template driven approach and anoter one with using of reactive form.

@Component({
  template: '<input [(ngModel)]="model.value">'
})
export class QuestionTemplateInputComponent {
  public model: any;

  ngOnInit(): void {
    this.model = { 
      value: 'value' 
    };
  }
}

@Component({
  template: '<form [formGroup]="formGroup"><input formControlName="value"></form>'
})
export class QuestionReactiveInputComponent implements OnInit {
  public formGroup: FormGroup;
  
  constructor (
    private readonly formBuilder: FormBuilder
  ) { }
  
  ngOnInit(): void {
    this.formGroup = this.formBuilder.group({
      value: ['value']
    });
  }
}

And here are also two tests in order to verify each component.

  let fixture1: ComponentFixture<QuestionTemplateInputComponent>;
  let fixture2: ComponentFixture<QuestionReactiveInputComponent>;

  ...

  it('verifies template input', () => {
    fixture1.detectChanges();
    const input: HTMLInputElement = fixture1.nativeElement.querySelector('input');
  
    expect(input.value).toBe('value'); // FAIL: Expected '' to be 'value'.
  });

  it('verifies reactive input ', () => {
    fixture2.detectChanges();
    const input: HTMLInputElement = fixture2.nativeElement.querySelector('input');
  
    expect(input.value).toBe('value'); // PASSED
  });

Why only one of them passes?


Solution

  • I think there are some async tasks that need to complete for the template approach, check this out.

    Try this:

    it('verifies template input', () => {
        fixture1.detectChanges();
        fixture.whenStable().then(() => {
           const input: HTMLInputElement = fixture1.nativeElement.querySelector('input');
           expect(input.value).toBe('value');
        });
      })
    

    fixture.whenStable ensures that the current promises (async tasks) have completed before carrying forward.