1
votes

I am working on Angular 9 with Material components. I want to show some values with in mat-select component.

Below is app.component.html

<h2> Angular - Material </h2>

<mat-form-field>
  <mat-label>Type</mat-label>
  <mat-select >
    <mat-option value="string">Small text</mat-option>
    <mat-option value="number">Number</mat-option>
    <mat-option value="date">Date</mat-option>
  </mat-select>
</mat-form-field>

<hr>

My app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'angular-playground';
}

When I run app with ng serve then I can see select box with all options.

<mat-select> showing options

But when I try to test this component with karma ng test then I am not getting any options in the select box. I tried inspecting HTML DOM and I am not seeing any option tags with in select and there are no errors in the console.

enter image description here

app.component.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { MatFormFieldModule } from '@angular/material/form-field'; 
import {MatSelectModule} from '@angular/material/select'; 

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule, MatFormFieldModule, MatSelectModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});

This is a so basic angular application and I have a simple component with only select box. Not sure why it is not showing options in test.

Below is my app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule } from '@angular/material/form-field'; 
import {MatSelectModule} from '@angular/material/select'; 


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatFormFieldModule,
    MatSelectModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Please help me on this.

1
Do you show any errors? My guess is that there should be some errors reported by the angular while trying to run the test. Also, it's not clear what AppMaterialModule is, please add its code. Here my guess is that it does not include MatFormFieldModule, MatSelectModule or something else that is needed for the AppComponent. BTW, I'd mock all this stuff out anyway instead of using real material components.Alexander Leonov
AppMaterialModule just has MatFormFieldModule, MatSelectModule modules. Please check my updated test file. I replaced AppMaterialModule with MatFormFieldModule and MatselectModule for simplicity and please check new screen shot, there are no errors in the console. And how do you mock these components ? can you please provide any tutorial reference?Pradeep
I probably don't get something here. What exactly do you expect that does not work the way you think it should? What do you want your test to test? Right now your test just checks the fact that your component can be instantiated successfully, and since it does pass it just means that you set all dependencies up correctly. If you want your test to do more than that - well, you need to put it in the test then... but what exactly?Alexander Leonov
the options are not in the DOM until select is closed. To show the options you should open the select. To do so get mat-select as view child in your component and then in the test call open over the select. Note opening of the select has animation by default so you may need to make your test fake async and call tick and detect changes after try to open the selectwnvko

1 Answers

0
votes

you must trigger the toggle of the MatSelectComponent to display your list of options like that:

const matSelectComponent = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;
fixture.detectChanges();

Now you can access to your options with:

const matOptionComponent = fixture.debugElement.queryAll(By.directive(MatOption));