Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No provider for $injector in Angular Testing

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?

like image 870
Edgar Quintero Avatar asked Feb 12 '19 13:02

Edgar Quintero


People also ask

What is null injector in angular?

The Null Injector does not contain any providers. Its job is to throw No provider for Service error. But if we decorate the dependency with @Optional decorator, then it will return null instead of throwing an error.

Which function is used to inject a service into a test function?

To test a service, you set the providers metadata property with an array of the services that you'll test or mock. content_copy let service: ValueService; beforeEach(() => { TestBed. configureTestingModule({ providers: [ValueService] }); }); Then inject it inside a test by calling TestBed.

What is angular TestBed?

TestBed is the primary api for writing unit tests for Angular applications and libraries.


1 Answers

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.

like image 87
Koen Meijer Avatar answered Nov 15 '22 10:11

Koen Meijer