0

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 Answers 2

2

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);
  });
});
Sign up to request clarification or add additional context in comments.

Comments

0

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);
  });

Comments

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.