Angular 6 - Unit Testing Mat-Select
Solution 1
This one is worked for me in Angular 7
const debugElement = fixture.debugElement;
// open options dialog
const matSelect = debugElement.query(By.css('.mat-select-trigger')).nativeElement;
matSelect.click();
fixture.detectChanges();
// select the first option (use queryAll if you want to chose an option)
const matOption = debugElement.query(By.css('.mat-option')).nativeElement;
matOption.click();
fixture.detectChanges();
fixture.whenStable().then( () => {
const inputElement: HTMLElement = debugElement.query(By.css('.ask-input')).nativeElement;
expect(inputElement.innerHTML.length).toBeGreaterThan(0);
});
Solution 2
After some testing I found an answer (at least for my code) and hope, that this is helpful to you as well:
When I looked at the DOM, when the application is running, I noticed that the default value of the mat-select is inside this DOM structure:
<mat-select>
<div class="mat-select-trigger">
<div class="mat-select-value">
<span class="something">
<span class="something">
The value is here!
But in my case, I had a form builder in my .ts file and it was used in ngOnInit()
. It seems that the normal TestBed.createComponent(MyComponent)
does not call ngOnInit()
. So I had to do that in order to get the value. Otherwise there was just a placeholder span
.
So, my final code looks like this:
it('should validate the drop down value if it is set by default', async () => {
const matSelectValueObject: HTMLElement = fixture.debugElement.query(By.css('.mat-select-value')).nativeElement;
component.ngOnInit();
fixture.detectChanges();
const innerSpan =
matSelectValueObject.children[0].children[0]; // for getting the inner span
expect(innerSpan.innerHTML).toEqual(3); // or '3', I did not test that
});
By the way I'm using Angular 7, in case this matters.
Solution 3
Helper method for your page object to set the option by text:
public setMatSelectValue(element: HTMLElement, value: string): Promise<void> {
// click on <mat-select>
element.click();
this.fixture.detectChanges();
// options will be rendered inside OverlayContainer
const overlay = TestBed.get(OverlayContainer).getContainerElement();
// find an option by text value and click it
const matOption = Array.from(overlay.querySelectorAll<HTMLElement>('.mat-option span.mat-option-text'))
.find(opt => opt.textContent.includes(value));
matOption.click();
this.fixture.detectChanges();
return this.fixture.whenStable();
}
Solution 4
let loader = TestbedHarnessEnvironment.loader(fixture);
const matSelect = await loader.getAllHarnesses(MatSelectHarness);
await matSelect[0].clickOptions();
const options = await matSelect[0].getOptions();
expect(await options[0].getText()).toMatch("");
expect(await options[1].getText()).toMatch('option1');
expect(await options[2].getText()).toMatch('option2');
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 10, 2022Comments
-
Admin about 2 years
1: The mat-select has 4 values, 1,2,3,4.
The code below works good for the select. So I'd like to share if it helps the readers.
it('check the length of drop down', async () => { const trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement; trigger.click(); fixture.detectChanges(); await fixture.whenStable().then(() => { const inquiryOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); expect(inquiryOptions.length).toEqual(4); }); });
2: I need another test to verify the default value in the same mat-select is 3 or not. When page loads the default value for the drop down is set to 3.
it('should validate the drop down value if it is set by default', async () => { const trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement; trigger.click(); fixture.detectChanges(); await fixture.whenStable().then(() => { const inquiryOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); const value = trigger.options[0].value; expect(value).toContain(3); }); });
Any help is appreciated.
-
Zozo about 5 yearsYou have a typo: detechChanges -> detectChanges
-
Sunil Garg almost 4 yearshow can i test the same in e2e?
-
Stephen over 2 years
const options
didn't get populated until I addedawait matSelect[0].open();
. -
AlignedDev over 2 yearsI didn't know about the Component Harnesses before this. Thanks! There's more information at github.com/angular/components/blob/master/guides/… and they encourage using this.