2

I'm wondering what is the correct way to test about the box checked and binded value are changed?

This is my HTML

     <div>
      <mat-checkbox class="col-md-9 text-right" id="checkid" name="checkid"
                    [checked]="this.isChecked"
                    (change)="this.isChecked = !isChecked">
        CheckBoxLabel
      </mat-checkbox>
    </div>

Then I tested by

const checkboxElem = fixture.debugElement.query(By.css('mat-checkbox')).nativeElement;
expect(checkboxElem.checked).toBeFalsy(); //pass
expect(comp.isChecked).toBeFalsy(); //pass
checkboxElem.click();
fixture.detectChanges();
expect(checkboxElem.checked).toBeTruthy(); //fail
expect(comp.isChecked).toBeTruthy(); //fail

The second expect always fails because the checkboxElem.checked=false all the time. I searched around 5 posts about the issue and have tried the following ways but none of those works:

  1. Made this test async and add whenStable(), same result
  2. Use the query By id, same result
  3. Put the text in label and defined element by fixture.debugElement.query(By.css('mat-checkbox label')).nativeElement, same result

In the debug mode, I cannot see the box of checkbox but only the label. I'm not sure how does jasmine click that element exactly.

2 Answers 2

2

Do you have MatCheckboxModule imported in your imports array of TestBed.configureTestingModule? I would import it to render the checkbox and that way you won't only see the label. Doing this a lone might fix it.

If that doesn't fix it, I would still have the import in the imports array and I would do triggerEventHandler.

const checkboxElem = fixture.debugElement.query(By.css('mat-checkbox'));
expect(checkboxElem.checked).toBeFalsy(); //pass
expect(comp.isChecked).toBeFalsy(); //pass
checkboxElem.triggerEventHandler('change', { }); // change this line
fixture.detectChanges();
// this bottom line will always fail because checkboxElem is now stale, 
// you need to grab a new reference
// expect(checkboxElem.checked).toBeTruthy(); //fail
const newCheckboxElem = fixture.debugElement.query(By.css('mat-checkbox')).nativeElement;
expect(newCheckboxElem.checked).toBeTruthy();
expect(comp.isChecked).toBeTruthy(); //fail

Learn more about triggerEventHandler here.

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

2 Comments

Thank you for the quick reply, and your link is very helpful! But I imports the MatCheckModule and tried to use triggerEventHandler, but got the error: TypeError: checkboxElem.triggerEventHandler is not a function.
Oops, I think it should have been fixture.debugElement.query(By.css('mat-checkbox')) (no nativeElement, first line changed). I have edited my answer.
2

In the end I tried this and it works. Using a dispatchEvent allows clicking the checkbox and the checked status became true. This is one of the suggestions in @AliF50 's triggerEventHandler link.

const checkboxElem = fixture.debugElement.query(By.css('mat-checkbox')).nativeElement;
expect(checkboxElem.checked).toBeFalsy();

checkboxElem.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(checkboxElem.checked).toBeTruthy();

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.