title: Angular testing with Jasmine and Karma - router-outlet errors and component creation test fail, for lazy-loaded component
body: <ul>
  <li>I have an Angular app that successfully builds and runs</li>
  <li>I'm running tests using <code>ng test</code></li>
  <li>I'm getting errors for all component creation</li>
  <li>I'm seeing a lot of errors in the console that suggest a failure to load <code>router-outlet</code></li>
  <li>I'm an Angular test noob so any comments on what I could try/look at may help</li>
  </ul>
  
  <hr>
  
  <p><strong>UPDATE</strong> - the answer from @Sanket is useful, however I still have the issue. I've commented on his answer, to explain the remaining issue</p>
  
  <hr>
  
  <p><strong>Error relating to load of <code>BackupComponent</code></strong></p>
  
  <p>(I believe that router-outlet is an Angular component, not a Web Component, as the codebase has no references to <code>CUSTOM_ELEMENTS_SCHEMA</code>)</p>
  
  <pre><code>        &lt;div class="col-lg-7 col-xs-12"&gt;
      1. If 'router-outlet' is an Angular component, then verify that it is part of this module.
      2. If 'router-outlet' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
          &lt;/div&gt;
          &lt;div class="col-lg-7 col-xs-12"&gt;
            [ERROR -&gt;]&lt;router-outlet&gt;&lt;/router-outlet&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      Error: Template parse errors:
      'app-backup-list' is not a known element:
      1. If 'app-backup-list' is an Angular component, then verify that it is part of this module.
      2. If 'app-backup-list' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("&lt;div class="row"&gt;
          &lt;div class="col-lg-5 col-xs-12"&gt;
              [ERROR -&gt;]&lt;app-backup-list&gt;&lt;/app-backup-list&gt;
          &lt;/div&gt;
          &lt;div class="col-lg-7 col-xs-12"&gt;
      "): ng:///DynamicTestModule/BackupComponent.html@2:8
      'router-outlet' is not a known element:
      1. If 'router-outlet' is an Angular component, then verify that it is part of this module.
      2. If 'router-outlet' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
          &lt;/div&gt;
          &lt;div class="col-lg-7 col-xs-12"&gt;
            [ERROR -&gt;]&lt;router-outlet&gt;&lt;/router-outlet&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      "): ng:///DynamicTestModule/BackupComponent.html@5:6
      error properties: Object({ ngSyntaxError: true, ngParseErrors: [ 'app-backup-list' is not a known element:
      "): ng:///DynamicTestModule/BackupComponent.html@2:8, 'router-outlet' is not a known element:
      "): ng:///DynamicTestModule/BackupComponent.html@5:6 ] })
          at syntaxError (node_modules/@angular/compiler/fesm5/compiler.js:2430:1)
          at TemplateParser.push../node_modules/@angular/compiler/fesm5/compiler.js.TemplateParser.parse (node_modules/@angular/compiler/fesm5/compiler.js:20605:1)
          at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._parseTemplate (node_modules/@angular/compiler/fesm5/compiler.js:26171:1)
          at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileTemplate (node_modules/@angular/compiler/fesm5/compiler.js:26158:1)
          at node_modules/@angular/compiler/fesm5/compiler.js:26101:48
          at &lt;Jasmine&gt;
          at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileComponents (node_modules/@angular/compiler/fesm5/compiler.js:26101:1)
          at node_modules/@angular/compiler/fesm5/compiler.js:26019:1
          at Object.then (node_modules/@angular/compiler/fesm5/compiler.js:2421:33)
          at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndAllComponents (node_modules/@angular/compiler/fesm5/compiler.js:26017:1)
      Error: Expected undefined to be truthy.
          at &lt;Jasmine&gt;
          at UserContext.&lt;anonymous&gt; (src/app/backup/components/backup/backup.component.spec.ts:23:23)
          at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:391:1)
  </code></pre>
  
  <p><strong>backup.component.spec.ts</strong></p>
  
  <pre><code>import { async, ComponentFixture, TestBed } from '@angular/core/testing';
  
  import { BackupComponent } from './backup.component';
  
  describe('BackupComponent', () =&gt; {
    let component: BackupComponent;
    let fixture: ComponentFixture&lt;BackupComponent&gt;;
  
    beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [ BackupComponent ]
      })
      .compileComponents();
    }));
  
    beforeEach(() =&gt; {
      fixture = TestBed.createComponent(BackupComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });
  
    it('should be created', () =&gt; {
      expect(component).toBeTruthy();
    });
  });
  </code></pre>
  
  <p><strong>backup.component.html</strong></p>
  
  <pre><code>&lt;div class="row"&gt;
      &lt;div class="col-lg-5 col-xs-12"&gt;
          &lt;app-backup-list&gt;&lt;/app-backup-list&gt;
      &lt;/div&gt;
      &lt;div class="col-lg-7 col-xs-12"&gt;
        &lt;router-outlet&gt;&lt;/router-outlet&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  </code></pre>
  
  <p><strong>backup.component.ts</strong></p>
  
  <pre><code>import { Component } from '@angular/core';
  
  @Component({
    selector: 'app-backup',
    templateUrl: './backup.component.html',
    styleUrls: ['./backup.component.css']
  })
  export class BackupComponent {
  
    constructor() { }
  
  }
  </code></pre>
  
  <p><strong>backup.module.ts</strong></p>
  
  <pre><code>import { NgModule } from '@angular/core';
  import { CommonModule } from '@angular/common';
  import { ReactiveFormsModule, FormsModule } from '@angular/forms';
  import { AccordionModule } from 'ngx-bootstrap';
  
  import { BackupRoutingModule } from './backup-routing.module';
  import { BackupComponent } from './components/backup/backup.component';
  import { BackupEditComponent } from './components/backup-edit/backup-edit.component';
  import { BackupItemComponent } from './components/backup-item/backup-item.component';
  import { BackupListComponent } from './components/backup-list/backup-list.component';
  import { SharedModule } from '../shared/shared.module';
  import { CommonAngularWidgetsLibModule } from '@ecotech/common-angular-widgets-lib';
  
  @NgModule({
    declarations: [
      BackupComponent,
      BackupEditComponent,
      BackupItemComponent,
      BackupListComponent
    ],
    imports: [
      CommonModule,
      FormsModule,
      ReactiveFormsModule,
      AccordionModule,
      SharedModule,
      CommonAngularWidgetsLibModule,
      BackupRoutingModule
    ]
  })
  export class BackupModule { }
  </code></pre>
  
  <p><strong>backup.routing.module.ts</strong></p>
  
  <pre><code>import { NgModule } from '@angular/core';
  import { Routes, RouterModule } from '@angular/router';
  
  import { BackupComponent } from './components/backup/backup.component';
  import { AuthGuard } from '../guards/auth.guard';
  import { BackupEditComponent } from './components/backup-edit/backup-edit.component';
  import { PendingChangesGuard } from '../guards/pending-changes.guard';
  
  const routes: Routes = [{
    path: '',
    component: BackupComponent,
    canActivate: [AuthGuard],
    children: [{
      path: 'new',
      component: BackupEditComponent,
      canDeactivate: [PendingChangesGuard]
    }, {
      path: ':id',
      component: BackupEditComponent,
      canDeactivate: [PendingChangesGuard]
    }]
  }];
  
  @NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule]
  })
  export class BackupRoutingModule { }
  </code></pre>
  
  <p><strong>app.module.ts (cut down)</strong></p>
  
  <pre><code>declare var require: any;
  
  import { BrowserModule } from '@angular/platform-browser';
  import { NgModule, LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
  import { ReactiveFormsModule, FormsModule  } from '@angular/forms';
  import { DynamicFormModule } from './dynamic-form/dynamic-form.module';
  import { AppComponent } from './app.component';
  import { AppRoutingModule } from './app-routing.module';
  import { SharedModule } from './shared/shared.module';
  import { CoreModule } from './core/core.module';
  
  
  @NgModule({
    declarations: [
      AppComponent,
      ... custom components, not including BackupComponent
    ],
    imports: [
      FormsModule,
      BrowserModule,
      ReactiveFormsModule,
      DynamicFormModule,
      CoreModule,
      SharedModule,
      AppRoutingModule,
    ],
    providers:
    [
      ... providers for app internationalisation only
    ],
    bootstrap: [AppComponent],
    entryComponents: [ConfirmationComponent,
      CalibrationWidgetComponent,
      RunCalibrationPointModalComponent,
      ... other custom components
    ]
  })
  
  export class AppModule { }
  </code></pre>
  
  <p><strong>app.routing.module.ts (cut down)</strong> - responsible for the lazy loading of <code>BackupModule</code></p>
  
  <pre><code>import { NgModule } from '@angular/core';
  import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
  
  
  const appRoutes:  Routes = [
    { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
    ...
    { path: 'backups', loadChildren: './backup/backup.module#BackupModule' },
    ... other custom routes
  ];
  
  @NgModule({
    imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })],
    exports: [RouterModule]
  })
  
  export class AppRoutingModule { }
  </code></pre>