How to make a unit test for to check checkbox is checked in a component

908 views Asked by At

I have trouble with unit test in Angular 2+. And now I am trying the smaller example (similar to my component) to learn how to test a input checkbox with ngmodel. But it does not run.

Here my smaller example:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-foobar',
  template: `
    <label>
      <input type="checkbox" [ngModel]="foo" />
      Checkbox
    </label>
  `,
  styleUrls: []
})
export class FooBarComponent implements OnInit {
  private _foo: boolean;

  public get foo(): boolean {
    return this._foo;
  }

  ngOnInit() {
    this._foo = true;
  }
}

And the unit test:

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FooBarComponent} from "./foobar.component";
import {FormsModule} from "@angular/forms";

describe('FooBarComponent', () => {
  let component: FooBarComponent;
  let fixture: ComponentFixture<FooBarComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [FooBarComponent],
      imports: [FormsModule,]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FooBarComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should start with the checkbox checked', () => {
    const checkboxElement: HTMLInputElement = fixture.nativeElement.querySelector('input[type="checkbox"]');
    expect(checkboxElement.checked).toBe(true);
  });
});

And the component rendered by karma in the browser has the checkbox unchecked, but when this smaller example is rendered in real app, it shows the checkbox checked:

enter image description here

I don't know what I need to do to make it runs.

2

There are 2 answers

0
AliF50 On

Try the following (pay attention to comments with !!):

beforeEach(() => {
    fixture = TestBed.createComponent(FooBarComponent);
    component = fixture.componentInstance;
    // !! This first fixture.detectChanges() calls ngOnInit for us
    fixture.detectChanges();
  });

  it('should start with the checkbox checked', () => {
    // !! Since ngOnInit is called with the first fixture.detectChanges()
    // and it changes variables in the HTML, we should call
    // fixture.detectChanges() again
    
    fixture.detectChanges();

    const checkboxElement: HTMLInputElement = fixture.nativeElement.querySelector('input[type="checkbox"]');
    expect(checkboxElement.checked).toBe(true);
  });
0
tres.14159 On

I found it. It is is with await fixture.whenStable(), here the code of the test:

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from "@angular/forms";
import {FooBarComponent} from "./app-foobar.component";

describe('FooBarComponent', () => {
  let component: FooBarComponent;
  let fixture: ComponentFixture<FooBarComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [FooBarComponent],
      imports: [FormsModule,]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FooBarComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should start with the checkbox checked', async () => {
    await fixture.whenStable(); //Wait for finish render

    const checkboxElement: HTMLInputElement = fixture.nativeElement.querySelector('input[type="checkbox"]');
    expect(checkboxElement.checked).toBe(true);
  });
});