Angular 4 Error: No provider for ChildrenOutletContexts in Karma-Jasmine Test

11,394

Based on the clue provided by @John, I imported RouterTestingModule instead of importing RouterModule and APP_BASE_HREF. So, the following modification in app.component.spec.ts worked!

import { TestBed, async } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';

import { AppComponent } from './app.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule 
        FormsModule
      ],
      declarations: [
        AppComponent,
        DashboardComponent
      ]
    }).compileComponents();
  }));
Share:
11,394
bradd
Author by

bradd

It’s the journey not the destination that matters!

Updated on June 07, 2022

Comments

  • bradd
    bradd almost 2 years

    My Angular application is working properly, but I am keep getting Karma error when I run ng test command. I have attached app component, spec, module and html along with package.json file. Error looks like this:

    Failed: No provider for ChildrenOutletContexts!
    Error: No provider for ChildrenOutletContexts!
    at injectionError (http://localhost:9876/_karma_webpack_/vendor.bundle.js:39523:90)
    at noProviderError (http://localhost:9876/_karma_webpack_/vendor.bundle.js:39561:12)
    at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._throwOrNull (http://localhost:9876/_karma_webpack_/vendor.bundle.js:41003:19)
    at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._getByKeyDefault (http://localhost:9876/_karma_webpack_/vendor.bundle.js:41042:25)
    at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._getByKey (http://localhost:9876/_karma_webpack_/vendor.bundle.js:40974:25)
    at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_.get (http://localhost:9876/_karma_webpack_/vendor.bundle.js:40843:21)
    at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/vendor.bundle.js:47827:25)
    at NgModuleRef_.webpackJsonp.../../../core/@angular/core.es5.js.NgModuleRef_.get (http://localhost:9876/_karma_webpack_/vendor.bundle.js:48909:16)
    at resolveDep (http://localhost:9876/_karma_webpack_/vendor.bundle.js:49412:45)
    at createClass (http://localhost:9876/_karma_webpack_/vendor.bundle.js:49276:32)
    

    app.component.ts

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.less']
    })
    export class AppComponent {
      title = 'app';
    }
    

    app.component.html

    <a href="http://localhost:4200/dashboard">Dashboard</a>
    <a href="http://localhost:4200/user">User</a> 
    <router-outlet></router-outlet>
    

    app.component.spec.ts

    import { TestBed, async } from '@angular/core/testing';
    import { RouterModule, Routes } from '@angular/router';
    import { FormsModule } from '@angular/forms';
    import { APP_BASE_HREF } from '@angular/common';
    
    import { AppComponent } from './app.component';
    import { DashboardComponent } from './modules/dashboard/dashboard.component';
    
    describe('AppComponent', () => {
      const routes: Routes = [
        {
          path: '',
          redirectTo: 'dashboard',
          pathMatch: 'full'
        },
        {
          path: 'dashboard',
          component: DashboardComponent,
        },
        {
          path: 'user',
          loadChildren: 'app/modules/user/user.module#UserModule'
        }
      ];
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [
            RouterModule,
            FormsModule
          ],
          declarations: [
            AppComponent,
            DashboardComponent
          ],
          providers: [
            { provide: APP_BASE_HREF, useClass: routes }
          ]
        }).compileComponents();
      }));
    
      it('should create the app', async(() => {
        const fixture = TestBed.createComponent(AppComponent);
        const app = fixture.debugElement.componentInstance;
        expect(app).toBeTruthy();
      }));
    
      it('should have as title app', async(() => {
        const fixture = TestBed.createComponent(AppComponent);
        const app = fixture.debugElement.componentInstance;
        expect(app.title).toEqual('app');
      }));
    
      it('should render title in a h1 tag', async(() => {
        const fixture = TestBed.createComponent(AppComponent);
        fixture.detectChanges();
        const compiled = fixture.debugElement.nativeElement;
        expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
      }));
    });
    

    app.module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { RouterModule, Routes } from '@angular/router';
    
    import { AppComponent } from './app.component';
    import { DashboardComponent } from './modules/dashboard/dashboard.component';
    
    const routes: Routes = [
      {
        path: '',
        redirectTo: 'dashboard',
        pathMatch: 'full'
      },
      {
          path: 'dashboard', 
          component: DashboardComponent, 
      },
      {
        path: 'user',
        loadChildren: 'app/modules/user/user.module#UserModule'
      }
    ];
    
    @NgModule({
      declarations: [
        AppComponent,
        DashboardComponent,
      ],
      imports: [
        BrowserModule,
        FormsModule,
        RouterModule.forRoot(routes)
      ],
      providers: [],
      bootstrap: [AppComponent],
      exports: [RouterModule]
    })
    export class AppModule { }
    

    package.json

        ...
     "dependencies": {
        "@angular/animations": "^4.0.0",
        "@angular/common": "^4.0.0",
        "@angular/compiler": "^4.0.0",
        "@angular/core": "^4.0.0",
        "@angular/forms": "^4.0.0",
        "@angular/http": "^4.0.0",
        "@angular/platform-browser": "^4.0.0",
        "@angular/platform-browser-dynamic": "^4.0.0",
        "@angular/router": "^4.0.0",
        "core-js": "^2.4.1",
        "rxjs": "^5.1.0",
        "zone.js": "0.8.12"
      },
      "devDependencies": {
        "@angular/cli": "1.2.1",
        "@angular/compiler-cli": "^4.0.0",
        "@angular/language-service": "^4.0.0",
        "@types/jasmine": "~2.5.53",
        "@types/jasminewd2": "~2.0.2",
        "@types/node": "~6.0.60",
        "codelyzer": "~3.0.1",
        "jasmine-core": "~2.6.2",
        "jasmine-spec-reporter": "~4.1.0",
        "karma": "~1.7.0",
        "karma-chrome-launcher": "~2.1.1",
        "karma-cli": "~1.0.1",
        "karma-coverage-istanbul-reporter": "^1.2.1",
        "karma-jasmine": "~1.1.0",
        "karma-jasmine-html-reporter": "^0.2.2",
        "protractor": "~5.1.2",
        "ts-node": "~3.0.4",
        "tslint": "~5.3.2",
        "typescript": "~2.3.3",
    ....
    
    • Amit Chigadani
      Amit Chigadani almost 7 years
      Add {provide: Router, useClass: RouterModule}, to your providers in spec and check. and do import {Router, RouterModule} from "@angular/router";
    • John-Philip
      John-Philip almost 7 years
      You would better go with RouterTestingModule for your spec instead of the complete RouterModule. It may solve your issue.
    • bradd
      bradd almost 7 years
      Thank you @John. RouterTestingModule works for me.
    • John-Philip
      John-Philip almost 7 years
      Glad it worked for you @bpaans. You could post your solution here, with a minimal code sample as it will help other people having the same problem ;-)
    • bradd
      bradd almost 7 years
      @john sure! I posted answer yesterday but deleted later as it was kinda straight forward after your clue :)
    • John-Philip
      John-Philip almost 7 years
      @bpaans, thanks its better for everyone I think to have a clear answer.