3
votes

I'm writing the first test and dealing with this error:

Error: Type SearchComponent is part of the declarations of 2 modules: AppModule and DynamicTestModule! Please consider moving SearchComponent to a higher module that imports AppModule and DynamicTestModule. You can also create a new NgModule that exports and includes SearchComponent then import that NgModule in AppModule and DynamicTestModule.

In my app I have only one module: AppModule.ts. And SearchComponent is declared only there. If I create a second module (aka ChildModule) and move SearchComponent there, the error message will have the same content but the name of a module will be changed from AppModule to ChildModule. I have the same error in every component I have.

If I remove AppModule from the imports in spec file, and add NO_ERRORS_SCHEMA, the error disappears.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule  } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { OtherComponentOne} from './tools/features/other-component-one.component';
import { OtherComponentTwo} from './tools/features/other-component-two.component';
import {routing} from "./app.routes";
import { environment } from '../environments/environment';
import {SearchComponent} from "./tools/features/search/search.component";
import {FilterPipe} from "./tools/shared/filter-pipe/filter.pipe";
import { SomeDirective } from './tools/shared/directives/some.directive';
import {ServiceOne} from "./tools/services/service-one.service";
import {ServiceTwo} from "./tools/services/service-two.service";

@NgModule({
  declarations: [
  FilterPipe,
  AppComponent,
  OtherComponentOne,
  OtherComponentTwo,
  SearchComponent,
  SomeDirective 
],
imports: [
  routing,
  HttpClientModule,
  BrowserModule,
  FormsModule,
  CommonModule,
  ReactiveFormsModule
],
exports: [SomeDirective ],
providers: [ServiceOne, ServiceTwo],
bootstrap: [AppComponent]
})
export class AppModule {}

Search.component.spec.ts

import {TestBed, async, ComponentFixture} from '@angular/core/testing';
import { SearchComponent } from './search.component';
import { ServiceOne} from '../../services/service-one';
import { ServiceTwo} from '../../services/service-two';
import { FilterPipe } from '../../shared/filter-pipe/filter.pipe';
import {AppModule} from "../../../app.module";

describe('Search Component', () => {
  let component: SearchComponent;
  let fixture: ComponentFixture<SearchComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        SearchComponent, FilterPipe
      ],
      imports: [AppModule], <----If I have NO_ERRORS_SCHEMA here instead of AppModule, test passes
      providers: [ServiceOne, ServiceTwo]
    });
    fixture = TestBed.createComponent(SearchComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be initialized', async(() => {
   expect(component).toBeTruthy();
  }));
});
1
Because you're bringing the whole AppModule into the tests, which already declares SearchComponent, then declaring SearchComponent again. That's what the error message tells you. Either don't declare that component again or, probably better, don't import absolutely everything into the TestBed - there's not much test isolation if your whole application's in there.jonrsharpe
@jonrsharpe so instead of importing AppComponent, I should manually import all the required modules (like HttpClientModule, FormsModule, etc)?Anna Olshevskaia
A single component shouldn't need that many other modules - for example, HttpClientModule should only be required by services, and you can mock out any services used by the component. And with the NO_ERROR_/CUSTOM_ELEMENTS_SCHEMA you can shallow render to remove the dependency on any child components. I'd recommend running through the guidance on testing: angular.io/guide/testing.jonrsharpe

1 Answers

5
votes

Please remove AppModule from your Search.component.spec.ts

Your test using TestingModule (DynamicTestModule) which is from TestBed. Apparently, you declared your SearchComponent when configuring TestingModule in the mean time you imported AppModule that you also declared your SearchComponent. That causes error message.