My Angular app uses the oidc-client UserManager class to manage OAuth authentication.
I have a service as below
export class AuthService {
private userManager: UserManager
private readonly configService: ConfigService;
constructor(configService: ConfigService) {
this.configService = configService;
}
...
async load(): Promise<any> {
config = this.configService.getConfig();
this.userManager = new UserManager(config);
const user = await this.userManager.getUser();
...
And my spec file setup is as below:
beforeEach(() => {
const spy = jasmine.createSpyObj('UserManager', ['getUser']);
spy.getUser.and.returnValue(mockUser);
const configSpy = jasmine.createSpyObj('ConfigService', ['getConfig']);
configSpy.getConfig.and.returnValue(mockConfig);
TestBed.configureTestingModule({
providers: [
AuthenticationService,
{ provide: UserManager, useValue: spy },
{ provide: AppConfigService, useValue: configSpy }
]
});
authService = TestBed.inject(AuthenticationService);
appConfigSpy = TestBed.inject(ConfigService) as jasmine.SpyObj<ConfigService>;
userManagerSpy = TestBed.inject(UserManager) as jasmine.SpyObj<UserManager>;
});
...and my first test case is :
it('should initialise the user manager', async () => {
// arrange
userManagerSpy.getUser.and.resolveTo(mockUser);
appConfigSpy.getConfig.and.returnValue(mockConfig);
// act
await authService.load();
// assert
expect(userManagerSpy).toHaveBeenCalled();
});
I'm getting a 404 error when running tests and I'm guessing the new UserManager(config) and/or the this.userManager.getUser() is trying to make an httpRequest when I want it to return the mock values.
How do I spyOn userManager and mock the return value from getUser()?
My understanding was that the TestBed.configureTestModule providers is for setting up the services which are DI'd into the service, not members of the service itself.
You need to spy on a constructor. In JS world you can do something like this
Topic about spying on constructor: Spying on a constructor using Jasmine
Instead of ... You can create a spy/mock and later check if #getUser() function was called. Or you can simply create Moco implementation for #getUser().
However remember that "Everytime a mock returns a mock a fairy dies". In other words - this is not the best way to write test and it indicates problem with code quality. If the UserManager was created inside function - it's not the service and I think it should not have logic.
Maybe you can refactor the code in a way that the config is used to call method of a service injected in constructor of AuthService?