6

I've been trying to setup testing in our Hybrid AngularJS/NG6 App but wow is this difficult to do. I keep getting constant errors. The latest is the following:

Error: StaticInjectorError(DynamicTestModule)[$injector]:

StaticInjectorError(Platform: core)[$injector]:

NullInjectorError: No provider for $injector!

I have the following component:

import { Component, OnInit, Input, Inject } from '@angular/core';
import { DashboardService } from '../../services/dashboard/dashboard.service';

@Component({
    templateUrl: './views/components/dashboard/dashboard.component.html'
})
export class DashboardComponent implements OnInit {
    @Input()
    Session;
    Util;
    constructor(
        private _dashboardService: DashboardService,
        @Inject('Session') Session: any,
        @Inject('Util') Util: any
    ) {
        this.Session = Session;
        this.Util = Util;
    }

    ngOnInit() {
        this._dashboardService
            .getPrograms(this.Session.user.organization)
            .subscribe(
                data => {
                    console.log(data);
                },
                error => {
                    console.log(error);
                }
            );
    }
}

That works perfectly fine. I can pull in data from our API. On the flip side I have this spec file:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';

import { DashboardComponent } from './dashboard.component';
import { DebugElement } from '@angular/core';

import { DashboardService } from '../../services/dashboard/dashboard.service';
import { ApiService } from '../../services/api.service';

import { HttpClientModule } from '@angular/common/http';

describe('The Dashboard', () => {
    let component: DashboardComponent;
    let fixture: ComponentFixture<DashboardComponent>;
    let de: DebugElement;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                CommonModule,
                FormsModule,
                ReactiveFormsModule,
                HttpClientModule
            ],
            declarations: [DashboardComponent],
            providers: [
                {
                    provide: 'Util',
                    useFactory: ($injector: any) => $injector.get('Util'),
                    deps: ['$injector']
                },
                {
                    provide: 'Session',
                    useFactory: ($injector: any) => $injector.get('Session'),
                    deps: ['$injector']
                },
                DashboardService,
                ApiService            
            ]
        })
            .overrideComponent(DashboardComponent, {
                set: {
                    templateUrl:
                        '/dist/views/components/dashboard/dashboard.component.html'
                }
            })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(DashboardComponent);
        component = fixture.componentInstance;
        de = fixture.debugElement;
        fixture.detectChanges();
    });

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

When I run this spec file I get the error listed above. I have no idea what the error is trying to tell me as it is very vague.

How do I provide the $Injector module correctly into the spec file?

Edgar Quintero
  • 4,223
  • 2
  • 34
  • 37

1 Answers1

4

I also tried to test Angular parts within my hybrid application with dependencies to AngularJS, but I did not succeed in it. To test either an AngularJS part with Angular dependencies or an Angular part with AngularJS dependencies within a hybrid is very difficult.

I found two possible solutions from this post on GitHub
- Completely mock the parts from the other framework.
- Create mini-apps that contain all dependencies from the other framework.

Koen Meijer
  • 811
  • 11
  • 19
  • You are pretty much right, I ended up not using AngularJS parts (i.e. $Injector) in the test as that was a huge headache, and no documentation anywhere. I created a new mini Service that holds all the AngularJS stuff I'm using in it and test that instead. Problem solved. – Edgar Quintero Feb 12 '19 at 20:32
  • Hey @EdgarQuintero, Can you please share the sample to mock the $injector. I'm also stuck in the same and I tried mocking $injector, but it's not working. – Neeraj Shende Dec 17 '19 at 13:50
  • @NeerajShende The Injector issue was really because of a `SessionService` that returns the user and all other stuff. I just created a `MockSessionService extends SessionService` class that exists in the same `spec` file, inside that class it also mocks all the functions in the real SessionService just return some static value. For example, inside the MockSessionService class (that extends SessionService), the `getToken` function just returns some random string. – Edgar Quintero Dec 18 '19 at 20:59