Angular 7: сбой теста для одного компонента связан с другим компонентом

#angular #karma-jasmine

#angular #karma-jasmine

Вопрос:

Я тестирую компонент, но тест завершается неудачей, но причина сбоя связана с другим компонентом, который я не объявил в тесте:

 FooterComponent should create
Failed: Component SplashComponent is not part of any NgModule or the module has not been imported into your module.
  

введите описание изображения здесь

Нижний компонент:

 @Component({
  selector: 'app-footer',
  templateUrl: './footer.html',
  styleUrls: ['./footer.scss']
})
export class FooterComponent implements OnInit {
  public date: number;
  public brandName: string;

  constructor(
    private config: Configuration) {
    }

  ngOnInit() {
    this.brandName = this.config.getConfigOption('brandName');
    this.date = new Date().getFullYear();
  }

}
  

Тест:

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

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

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

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

NgModule для справки:

 @NgModule({
  declarations: [
    AppComponent,
    SplashComponent,
    FooterComponent,
   .....
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    CollapseModule.forRoot(),
    ReactiveFormsModule,
    FormsModule,
    HttpClientModule
  ],
  schemas: [ NO_ERRORS_SCHEMA ],
  providers: [
   .....
  ],

  bootstrap: [AppComponent]
})
export class AppModule { }
  

Эта же проблема повторяется для тестов для других компонентов.

РЕДАКТИРОВАТЬ: В ответах упоминается шаблон нижнего колонтитула, содержащий дочерние компоненты, в них этого нет. Однако, если я добавлю SplashComponent в объявление test, это сработает, но затем его место займет другой компонент.

введите описание изображения здесь

Что-то где-то создает иерархию.

Шаблон нижнего колонтитула:

 <footer>
<div class="container">
  <div class="row">
    <div class="col-md-12">
      <div class="links">
        <ul>
          <li><a [routerLink]="['/support']">Support</a></li>
          <li><a [routerLink]="['/terms']">Terms amp; Privacy</a></li>
        </ul>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-md-12">
      <div class="copyright">
        <p>
          amp;copy; {{ date }} {{ brandName}}. Made with <span class="icon-favourites"></span> by 
          <a href="" target="_blank"></a>.
        </p>
      </div>
    </div>
  </div>
</div>
</footer>
  

РЕДАКТИРОВАТЬ: 2

Шаблон App.component:

 <app-header></app-header>
<main>
  <div class="container">
    <router-outlet></router-outlet>
  </div>
</main>
<app-footer></app-footer>
  

Ответ №1:

Проблема вызвана тем фактом, что вы импортируете RouterTestingModule с маршрутами, скорее всего, с путем, связанным с SplashComponent .

Если вы не планируете тестировать определенные маршруты с конкретными компонентами, вам не следует настраивать маршруты на RouterTestingModule . Реорганизуйте в следующее:

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

Комментарии:

1. Спасибо. Он не содержит дочернего компонента, однако объявление его в тестовом модуле работает. Другой компонент заменяет компонент splash (см. Обновление). Существует ли другой механизм, который создавал бы иерархические отношения с несвязанными компонентами?

Ответ №2:

С помощью вашего теста вы можете напрямую импортировать дочерний компонент в свой тест или вы можете имитировать дочерние компоненты. Смотрите:

 TestBed.configureTestingModule({
  imports: [
     ...
  ],
  declarations: [
    FooterComponent,
    MockSplashComponent,
  ],
  providers: [
    ...
  ]
})

... 

@Component({
  selector: 'app-asplash-component',
  template: ''
})
export class MockSplashComponent{

}
  

Комментарии:

1. Спасибо. Нижний компонент обрабатывает другие (не связанные) компоненты как дочерние компоненты. Я не уверен, что является причиной этого. Я обновил вопрос с помощью шаблона нижнего колонтитула.

2. Странно, похоже, вы откуда-то импортировали все объявления вашего модуля. Вы уверены, что в вашем импорте есть только RouterTestingModule ?

3. На тестовом уровне для нижнего колонтитула? Да, только RouterTestingModule. Проблема повторяется и с другими компонентами.

4. Понятия не имею, извините.

5. Я передавал объект routes! Спасибо за помощь.