Search code examples
angularangular-materialangular-test

How do I import a shared module (with Angular Material) to test Angular applications?


I'm trying to start creating tests for an Angular sample application that also uses Angular Material and Angular Flex layout.

Within my app, I'm already using a shared module to import all the Angular Material components. It goes like this:

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

import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatNativeDateModule } from '@angular/material/core';
import { MatTabsModule } from '@angular/material/tabs';

@NgModule({
  imports: [
    MatButtonModule, MatToolbarModule, MatIconModule, MatCardModule,
    MatDatepickerModule, MatFormFieldModule, MatInputModule,
    MatTabsModule, MatNativeDateModule
  ],
  exports: [
    MatButtonModule, MatToolbarModule, MatIconModule, MatCardModule,
    MatDatepickerModule, MatFormFieldModule, MatInputModule,
    MatTabsModule
  ]
})
export class MaterialModule {}

When I first ran ng test every component would fail the basic creation test. Most certainly the messages mentioned Angular Material tags. So, I tried this:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AccountComponent } from './account.component';
import { MaterialModule } from '../material.module';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [AccountComponent],
      imports: [
        RouterTestingModule,
        MaterialModule
      ]
    }).compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

This test, however, did not pass. However, I tried importing the modules manually, one after the other as the error messages stated:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AccountComponent } from './account.component';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatTabsModule } from '@angular/material/tabs';
import { MatCardModule } from '@angular/material/card';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [AccountComponent],
      imports: [
        RouterTestingModule,
        MatFormFieldModule,
        MatTabsModule,
        MatCardModule
      ]
    }).compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

To my surprise, the test now passes. And I really can't figure why.

Is there anyway I can import a shared module when testing just like I do in the regular application?


Solution

  • I have to thank @yurzui on this one. He requested the error message I was getting on my test.

    As it turns out, I wasn't really paying attention to the message and I noticed when copying to post here. The error message did mentioned an unknown tag which I know is from Angular Material. However, just below it was mentioning the problem in a different component.

    The catch here is that AccountComponent is a tabbed page which displays another two components which on the testing module did not import the material module. I feel embarassed.