'How to spy OKTA authStateService.authState$ in angular unit testing using karma jasmine
I have the below authentication guard in my angular application which using OKTA to authenticate.
export class AuthenticationGuard implements canActivate {
iaAuthenticated: boolean;
userDetails: any = null;
constructor(@Inject(OKTA_AUTH) private oktaAuth: OktaAuth, public authStateService:
OktaAuthStateServuce) { }
canActivate = async (next: aCtivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any>
=> {
try {
this.authStateService.authState$.subscribe(
(response) => {
this.isAuthenticated = response.isAuthenticated;
}
);
if (this.isAuthenticated) {
this.userDetails = this.oktaAuth.getUser();
} else { return false; }
} catch { return false; }
}
}
and this is the spec code for the same which I written
export class OktaAuthMock {
isAuthenticated() {
return true;
}
getUser() {
return {
email: ‘[email protected]’,
name: ‘test’
};
}
};
authState$(){
return {isAuthenticated: true}
}
fdescribe(‘test AuthenticationGuard’, () => {
let service: AuthenticationGuard;
beforeEach(() => {
Testbed.configureTestingModule({
Imports: [HttpClientTestingModule],
Providers: [
{
provide: OktaAuthStateService,
useClass: OktaAuthMock
},
{
Provide: OKTA_AUTH,
useValue: {}
}
]
)};
service = Testbed.inject(AuthenticationGurad)
});
it(‘test canActivate method’, () => {
const authService: OktaAuthStateService = Testbed.inject(OktaAuthStateService);
spyOn<any>(authService. ‘authState$’).and.returnValue(of({ isAuthenticated: true }));
service.canActivate(null, null);
expect(service.canActivate).tobeTruthy();
});
)};
There is no error in the code but I tried to spyon the OktaAuthStateService like above and the lines of code in ts is not covered in unit test. Kindly help to do it correctly.
Solution 1:[1]
It looks like there might be a few items to address here.
- Regarding your specific question about mocking Okta, you need to provide mocks for both
OKTA_AUTHandOktaStateService. The mocks should match the calls being made. For example, you mocked a methodauthState$(), but in theOktaStateService, it's not a method, it's a property on the class. - You also haven't provided a mock for
OKTA_AUTH. You'll want to do so, which will allow you to test this without importing theHttpClientTestingModule. - Your casing and spelling of the properties and definitions should be double-checked in both your guard as well as your test.
- FWIW, if you are creating a guard, consider implementing from
CanActivate. Or maybe this is a casing issue?
Here are some samples to reference as you work through this.
An example repo that shows how to implement a guard using Okta is oktadev/okta-angular-material-login-example. This is using an older version of the okta-angular SDK that doesn't use the OKTA_AUTH injection token, so you'll need to make appropriate adjustments. Of note look at
For examples of how to mock and spy on properties in Okta services, check out oktadev/okta-angular-dynamic-components-example. Of note look at
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AlisaDuncan |
