Failed: parentContexts.onChildOutletCreated is not a function

Issue

I’ve been working on the unit tests of an app and I run into a failure that I don’t seem able to find anywhere.
I’m currently using Iconic 5 with Angular 9.
Jasmine says:

StatisticsPage > should create
Failed: parentContexts.onChildOutletCreated is not a function
    at <Jasmine>
    at new IonRouterOutlet (http://localhost:9876/_karma_webpack_/node_modules/@ionic/angular/__ivy_ngcc__/fesm2015/ionic-angular.js:2723:1)
    at NodeInjectorFactory.IonRouterOutlet_Factory [as factory] (http://localhost:9876/_karma_webpack_/node_modules/@ionic/angular/__ivy_ngcc__/fesm2015/ionic-angular.js:2948:61)
    at getNodeInjectable (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:5993:1)
    at instantiateAllDirectives (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12984:1)
    at createDirectivesInstances (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12196:1)
    at Module.ɵɵelementStart (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:21289:1)
    at IonTabs_Template (http://localhost:9876/_karma_webpack_/node_modules/@ionic/angular/__ivy_ngcc__/fesm2015/ionic-angular.js:3081:30)
    at executeTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12156:1)
    at renderView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11926:1)
    at renderComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13505:1)
Expected undefined to be truthy.
Error: Expected undefined to be truthy.
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/statistics/statistics/statistics.page.spec.ts:39:23)
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:292:1)

This is the HTML page (the problem does not appear if I eliminate the tabs of the footer, so those are guilty of all this)

<ion-content>
<!-- HTML things happening here -->
<ion-content>

<ion-footer>

<ion-toolbar>
  <ion-tabs id='tabs'>
    <ion-tab-bar slot="bottom">
      <ion-tab-button (click)= "selectChart('personal')">
        <ion-icon name="person"></ion-icon>
        <ion-label>Personal statistics</ion-label>
      </ion-tab-button>
      <ion-tab-button>
        <ion-icon name="globe" (click)= "selectChart('national')"></ion-icon>
        <ion-label>National rates</ion-label>
      </ion-tab-button>
    </ion-tab-bar>
  </ion-tabs>
</ion-toolbar>
  
</ion-footer>

This is the test file:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ StatisticsPage ],
      imports: [IonicModule.forRoot(), RouterTestingModule],
      providers: [
        { provide: Storage, useClass: MockStorage },
        { provide: NavController, useClass: MockNavController },
        { provide: ChildrenOutletContexts, useClass: MockChildrenOutletContexts },
        { provide: ActivatedRoute, useClass: MockActivatedRoute },
        { provide: Router, useClass: MockRouter },
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(StatisticsPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

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

All the providers were created as jasmine asked for them, but when it ended asking for injections, I run into this issue. I’ve created most of them as empty classes and I’ve added methods as needed

Solution

Finally figured it out!
so, in the test file, the “ChildrenOutletContexts” should be provided, but not mocked!

providers: [
  { provide: Storage, useClass: MockStorage },
  { provide: NavController, useClass: MockNavController },
  { provide: ChildrenOutletContexts },
  { provide: ActivatedRoute, useClass: MockActivatedRoute },
  { provide: Router, useClass: MockRouter },
]

that solved everything! 🙂

Answered By – Dani

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published