Home > database >  Error: inject() must be called from an injection context, Error: Expected undefined to be truthy
Error: inject() must be called from an injection context, Error: Expected undefined to be truthy

Time:10-07

I am setting up a unit test for my app.component, I have imported everything necessary but I get an error that I do not understand, activate in my angular.json the "preserveSymlinks": true but the problem persists, how can I fix it?

The error: Error: inject() must be called from an injection context

Error inject

My ts file:

import { Component } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { LoginService } from 'is-common';
import { CookieService } from 'ngx-cookie';
import { Api } from 'is-common';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent {
    title = 'ghai-front';
    isLogged: boolean = false;
    constructor(private router: Router,
        private loginService: LoginService,
        private cookie: CookieService,
        public api: Api) {
        router.events.subscribe((val) => {
            if (val instanceof NavigationEnd)
                this.isLogged = this.loginService.isLogged() === true && val.url !== '/login';
        })
        this.loginService.setApiURL('/api-tacticas');
        this.loginService.setDefaultClient(2);
    }
}

My Test:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { Api } from 'is-common';
import { LoginService } from 'is-common';
import { HttpClientTestingModule } from '@angular/common/http/testing';


describe('AppComponent', () => {
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;
    let api: Api;
    let loginService: LoginService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                HttpClientTestingModule,
                RouterTestingModule
            ],
            declarations: [
                AppComponent
            ],
            providers: [
                Api,
                LoginService
            ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        api = TestBed.inject(Api);
        loginService = TestBed.inject(LoginService);
    });

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

My tsconfig.app.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "paths": { "@angular/": [ "../node_modules/@angular/" ] }
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

CodePudding user response:

I think the issue comes from Api, CookieService, or LoginService. I would mock these external dependencies.

Try this:

describe('AppComponent', () => {
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;
    // !! modify these lines !!
    let mockApi: jasmine.SpyObj<Api>;
    let mockLoginService: jasmine.SpyObj<LoginService>;
    let mockCookieService: jasmine.SpyObj<CookieService>;

    beforeEach(() => {
        // Create a new spy before each test
        // The first string is an identifier for the mocked object
        // The array of the strings are public methods
        // I don't know the public methods of API so we will give an empty object
        mockApi = {};
        mockLoginService = jasmine.createSpyObj<LoginService>('LoginService', ['isLogged', 'setApiURL', 'setDefaultClient']);
        mockCookieService = jasmine.createSpyObj<CookieService>('CookieService', ['get']);
        TestBed.configureTestingModule({
            imports: [
                HttpClientTestingModule,
                RouterTestingModule
            ],
            declarations: [
                AppComponent
            ],
            providers: [
                // !! Provide the mocks for all external dependencies
                { provide: Api, useValue: mockApi },
                { provide: LoginService, useValue: mockLoginService },
                { provide: CookieService, useValue: mockCookieService }
            ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
        }).compileComponents();
    });

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

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

I think the above should help you and it should work. I always mock external dependencies.

  • Related