No provider for $injector in Angular Testing
Asked Answered
E

1

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?

Erhard answered 12/2, 2019 at 13:30 Comment(0)
S
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.

Septilateral answered 12/2, 2019 at 19:4 Comment(3)
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.Erhard
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.Adanadana
@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.Erhard

© 2022 - 2024 — McMap. All rights reserved.