I am facing issues with test-coverage using jasmine, for that I am working with MsalService-Entra (Microsoft Authentication Library) and Angular 15, I am using a method to get All user accounts from a list that MsalService library provides us and the idea is to create a test-coverage for that, specificaly for this line:
this.msalService.instance.getAllAccounts().length
So I tried in many ways but still I am having problems mocking that getAllAccounts method from msaservice library, this is my code that I tried and I hope you could help me with that.
login.ts
checkAndSetActiveAccount() {
if (this.msalService.instance && this.msalService.instance.getAllAccounts().length > 0) {
const accounts = this.msalService.instance.getAllAccounts();
This is my login.spec.ts
let msalServiceMock: jasmine.SpyObj<MsalService>;
beforeEach(waitForAsync(() => {
msalServiceMock = jasmine.createSpyObj('MsalService', ['instance', 'getAllAccounts']);
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes(
[{path: 'home', component: HomeComponent}]
),
],
providers: [
{provide: MsalService, useValue: msalServiceMock}
],
declarations: [LoginComponent]
}).compileComponents();
}));
...
it('checkAndSetActiveAccount() check and validate Active Account', ()=> {
let mockAccounts =[
{ homeAccountId: '', environment:'', tenantId:'', username:'', localAccountId:'' }
];
//msalServiceMock = TestBed.inject(MsalService);
//mockMsalService.instance.setActiveAccount(mockData[0]);
//spyOn(msalServiceMock, 'instance').and.returnValue(mockAccounts);
spyOn(msalServiceMock.instance, 'getAllAccounts').and.returnValue(mockAccounts);
//spyOn(component.msalService.instance, 'getAllAccounts').and.returnValue(of(mockData));
component.checkAndSetActiveAccount();
Error on console:
Firefox 132.0 (Mac OS 10.15) LoginComponent processCredentials() is processing username and password checkAndSetActiveAccount() check and validate Active Account FAILED
Error: <spyOn> : getAllAccounts() method does not exist
Usage: spyOn(<object>, <methodName>) in node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js (line 9619)
<Jasmine>
Firefox 132.0 (Mac OS 10.15) LoginComponent processCredentials() is processing username and password username and password are empty strings FAILED
TypeError: this.msalService.instance.getAllAccounts is not a function in main.js (line 98918)
I have not implemented the exact MsalService
, but I have mocked the service to solve the test case.
We use createSpyObj
to mock the methods and the properties of the service. I set instance as null
so that it can be set on the test case.
msalServiceMock = jasmine.createSpyObj('MsalService', ['getAllAccounts'], {
instance: null,
});
I use `` to set the return value for the property instance
and set it to the scope of the same service, this is only for testing purposes. Due to typing issue I had to wrap it inside a as any
block.
(
Object.getOwnPropertyDescriptor(msalServiceMock, 'instance').get as any
).and.returnValue(component.msalService);
Then we can spy on the method and perform the checks.
it('checkAndSetActiveAccount() check and validate Active Account', () => {
let mockAccounts = [
{
homeAccountId: '',
environment: '',
tenantId: '',
username: '',
localAccountId: '',
},
];
(
Object.getOwnPropertyDescriptor(msalServiceMock, 'instance').get as any
).and.returnValue(component.msalService);
msalServiceMock.getAllAccounts.and.returnValue(mockAccounts as any);
component.checkAndSetActiveAccount();
expect(msalServiceMock.getAllAccounts).toHaveBeenCalled();
expect(component.data).toEqual(mockAccounts);
});
import { TestBed, ComponentFixture, waitForAsync } from '@angular/core/testing';
import { AppComponent, MsalService } from './app.component';
import { AppModule } from './app.module';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let msalServiceMock: jasmine.SpyObj<MsalService>;
beforeEach(waitForAsync(() => {
msalServiceMock = jasmine.createSpyObj('MsalService', ['getAllAccounts'], {
instance: null,
});
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
// RouterTestingModule.withRoutes([
// { path: 'home', component: HomeComponent },
// ]),
],
providers: [{ provide: MsalService, useValue: msalServiceMock }],
declarations: [AppComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('checkAndSetActiveAccount() check and validate Active Account', () => {
let mockAccounts = [
{
homeAccountId: '',
environment: '',
tenantId: '',
username: '',
localAccountId: '',
},
];
(
Object.getOwnPropertyDescriptor(msalServiceMock, 'instance').get as any
).and.returnValue(component.msalService);
msalServiceMock.getAllAccounts.and.returnValue(mockAccounts as any);
component.checkAndSetActiveAccount();
expect(msalServiceMock.getAllAccounts).toHaveBeenCalled();
expect(component.data).toEqual(mockAccounts);
});
});