Testing component fails NullInjectorError: No provider for Content!


#1

Hi I am trying to unit test a component in Ionic 3, It use to work fine before, but after adding tons of modifications the test is failing with the following log:

Chrome 65.0.3325 (Mac OS X 10.13.3) TransactionsTableComponent should display ten transactions as much FAILED
Error: StaticInjectorError[Content]:
StaticInjectorError[Content]:
NullInjectorError: No provider for Content!
at _NullInjector.get (webpack:///node_modules/@angular/core/esm5/core.js:923:0 <- test-config/karma-test-shim.js:1193:19)

I tried to search the problem and it seems that the test cannot resolve some providers from a parent page or something, I am not sure what is happening, because I am not using Content or explicitly declaring it on my component.ts

here is my spec.ts

import { DebugElement } from "@angular/core/src/debug/debug_node";
import { ComponentFixture, async, TestBed } from "@angular/core/testing";

/* import component to test  */
import { TransactionsTableComponent } from './transactions-table'
import { MyApp } from "../../app/app.component";
import { IonicModule } from "ionic-angular";
import { NavController } from "ionic-angular/navigation/nav-controller";
import { By } from "@angular/platform-browser";
import { ElementRef } from "@angular/core";

describe('TransactionsTableComponent',() => {
    let component: TransactionsTableComponent;
    let fixture: ComponentFixture<TransactionsTableComponent>;
    let debugElement: DebugElement;
    let htmlElement: HTMLElement;


    beforeEach(async(() => {

        TestBed.configureTestingModule({
            declarations: [
                TransactionsTableComponent, 
                MyApp],
            imports: [
                IonicModule.forRoot(MyApp),
            ],
            providers: [
            ]
        });

    }));

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

    afterEach(() => {
        fixture.destroy();
        component = null;
    });

    it('should display ten transactions as much', () => {
        fixture.detectChanges();
    });

    it('should have the right title', ()=>{
        fixture.detectChanges();
        debugElement = fixture.debugElement.query(By.css('h2'));
        let el = debugElement.nativeElement;
        expect(el.textContent).toContain('Mi actividad');
    });

});

and the component.ts

import { Component, Input } from '@angular/core';
import { TransactionEvent } from '../../app/models/transactions/transaction-event';
import { TransactionsDate } from "./../../app/models/transactions/transactions-date";

@Component({
  selector: 'transactions-table',
  templateUrl: 'transactions-table.html'
})
export class TransactionsTableComponent {

  @Input() transactionEvent: TransactionEvent;
  @Input() transactionsLoaded: TransactionsDate[];
  changeLog: string[] = [];
  numLoads: number = 6;

  private movementsError = "Aún no has realizado movimientos con este producto";

  constructor(
  ) {
  }

  doInfinite(infiniteScroll) {
    console.log('Begin async operation');
    setTimeout(() => {
      this.loadAWeek();
      console.log('Async operation has ended');
      infiniteScroll.complete();
    }, 500);
  }

  userHasTransactions() {
    return this.transactionEvent.transactionsDate.length >= 1;
  }

  loadAWeek() {
    for (let i = 0; i < 7; i++) {
      this.numLoads++;
      if (this.transactionEvent.transactionsDate[this.numLoads] != null) {
        this.transactionsLoaded.push(this.transactionEvent.transactionsDate[this.numLoads]);
      }
    }
  }
}

Has anyone run into this issue?


#2

Why are you importing it if you arent using it?


#3

Actually I forgot to erase it, as I tried to import and put in the providers array, it change the error to no provider for elementRef after that, when checking the constructor of Content, it seems to take as a parameter an elementRef attribute.


#4

Something weird is happening, after surfing the web, I tried to wrap the infinite-scroll into ion-content like this:

<ion-content>
  <ion-infinite-scroll class="hidden-lg" (ionInfinite)="doInfinite($event)">
    <ion-infinite-scroll-content></ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>

and then run

npm test

and woala!, it works, but… wait, my inifinite scroll stopped working on mobile, buahhhhh

what the heck is going on?