Unit Testing angular2 component with imported module

George Edwards picture George Edwards · Oct 26, 2016 · Viewed 17k times · Source

I am trying to write a test on a component which uses angular-material2, but when I add it to my testModule declarations I get:

Error: Template parse errors:
    'md-card-title' is not a known element:
    1. If 'md-card-title' is an Angular component, then verify that it is part of this module.
    2. If 'md-card-title' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message.

Adding MaterialModule to the declarations throws `Error: Unexpected module 'MaterialModule' declared by the module

DynamicTestModule' in config/spec-bundle.js (line 24994)

This is what my spec file looks like:

  beforeEach(() => TestBed.configureTestingModule({
    declarations: [],
    providers: [
      { provide: DataService, useValue: mockDataService },
      { provide: ActivatedRoute, useClass: MockActivatedRoute },
      { provide: Router, useValue: mockRouter },
      CellViewComponent
    ]
  }));

adding CellViewComponent to the declarations array causes the error to throw.

Answer

Paul Samsotha picture Paul Samsotha · Oct 26, 2016

When you use the TestBed.configureTestingModule, you're create a module from scratch for the test environment. So what ever you would need in the real application for the CellViewComponent to work, you also need to configure it in the testing module.

In your case, you're missing the Material card component. In the app you probably either imported the MaterialModule or the MdCardModule into your AppModule. So you need to do the same in the testing module

beforeEach(() => TestBed.configureTestingModule({
  imports: [ MaterialModule /* or MdCardModule */ ],
  declarations: [  CellViewComponent ],
  providers: [
    { provide: DataService, useValue: mockDataService },
    { provide: ActivatedRoute, useClass: MockActivatedRoute },
    { provide: Router, useValue: mockRouter },
  ]
}));