1

I am trying to write unit test for the login component below. This component has a constructor with @Inject. How do we test an angular component with @Inject in constructor? Can someone help? Thanks!

LoginComponent.ts

import { Component, Inject, OnInit } from '@angular/core'; import { OKTA_AUTH } from '@okta/okta-angular'; import { OktaAuth } from '@okta/okta-auth-js'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { isAuthenticated!: boolean; userName?: string; error?: Error; constructor(@Inject(OKTA_AUTH) public oktaAuth: OktaAuth) { } async ngOnInit() { this.isAuthenticated = await this.oktaAuth.isAuthenticated(); if (this.isAuthenticated) { const userClaims = await this.oktaAuth.getUser(); this.userName = userClaims.name; } } async login() { try { await this.oktaAuth.signInWithRedirect(); } catch (err: any) { console.error(err); this.error = err; } } async logout() { await this.oktaAuth.signOut(); } } 

LoginComponent.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing'; import { LoginComponent } from './login.component'; import { OktaAuth } from '@okta/okta-auth-js'; describe('LoginComponent', () => { let component: LoginComponent; let fixture: ComponentFixture<LoginComponent>; let authService: OktaAuth; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [LoginComponent], providers: [OktaAuth] }).compileComponents(); fixture = TestBed.createComponent(LoginComponent); component = fixture.componentInstance; authService = TestBed.inject(OktaAuth); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); 

Here is the error

Chrome Headless 114.0.5735.133 (Windows 10) LoginComponent should create FAILED Error: NG0204: Can't resolve all parameters for OktaAuth: (?). error properties: Object({ code: 204 }) at getUndecoratedInjectableFactory (node_modules/@angular/core/fesm2022/core.mjs:9227:15) at injectableDefOrInjectorDefFactory (node_modules/@angular/core/fesm2022/core.mjs:9217:16) at providerToFactory (node_modules/@angular/core/fesm2022/core.mjs:9263:52) at providerToRecord (node_modules/@angular/core/fesm2022/core.mjs:9247:25) at R3Injector.processProvider (node_modules/@angular/core/fesm2022/core.mjs:9144:24) at fn (node_modules/@angular/core/fesm2022/core.mjs:8975:59) at forEachSingleProvider (node_modules/@angular/core/fesm2022/core.mjs:9318:13) at forEachSingleProvider (node_modules/@angular/core/fesm2022/core.mjs:9315:13) at new R3Injector (node_modules/@angular/core/fesm2022/core.mjs:8975:9) at createInjectorWithoutInjectorInstances (node_modules/@angular/core/fesm2022/core.mjs:10591:12) 

I must miss something. Please let me know what I am missing. Thanks in advance.

tried to import both import { OKTA_AUTH } from '@okta/okta-angular'; import { OktaAuth } from '@okta/okta-auth-js';

1 Answer 1

2

This is where I ended up finding the answer: https://github.com/okta-samples/okta-angular-quickstart/blob/main/src/app/app.component.spec.ts

... import { OktaAuthStateService, OKTA_AUTH } from '@okta/okta-angular'; describe('AppComponent', () => { const authStateSpy = jasmine.createSpyObj('OktaAuthStateService', [], { authState$: of({ isAuthenticated: false }) }); const authSpy = jasmine.createSpyObj('OktaAuth', ['login']); beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ RouterTestingModule ], declarations: [ AppComponent ], providers: [ { provide: OktaAuthStateService, useValue: authStateSpy }, { provide: OKTA_AUTH, useValue: authSpy } // <-- see how you can provide the token, but provide your own stub/mock? ] }).compileComponents(); }); 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, Jake ! Your code works great.
@Jry glad to hear it :) Mind accepting the answer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.