After Angular CanActivate interface became deprecated, I've changed my guards for simple const functions based on official documentation. For example here is my inverseAuthGuard method, which seems working correctly:
export const inverseAuthGuard = (): boolean => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
router.navigate(['/visual-check']);
return false;
}
return true;
};
My problem is that, I want to write some unit tests for it and I don't know how can I inject a mock authService and a mockRouter into this function. I've watched this video, which explains how can I inject mock services into a class, but for my guard function I couldn't make it working.
I have tried some ways, but I couldn' find any solution. If I do this way:
describe('InverseAuthGuard', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
providers: [
{ provide: AuthService, useValue: AuthService },
{ provide: Router, useValue: Router },
],
});
});
fit('should return true on not authenticated user', () => {
const result = inverseAuthGuard();
expect(result).toBe(true);
});
});
I've got the following error:
NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`
If I do that way, what I saw in the video:
describe('InverseAuthGuard', () => {
const setupWithDI = (authService: unknown, router: unknown) =>
TestBed.configureTestingModule({
providers: [
{ provide: AuthService, useValue: authService },
{ provide: Router, useValue: router },
],
}).inject(inverseAuthGuard);
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
});
});
fit('should return true on not authenticated user', () => {
const mockAuthService: unknown = { isAuthenticated: () => true };
const mockRouter: Router = jasmine.createSpyObj(['navigate']);
setupWithDI(mockAuthService, mockRouter);
const result = inverseAuthGuard();
expect(result).toBe(true);
});
});
I've got the following error:
NullInjectorError: No provider for inverseAuthGuard!
Of course, I've tried providing inverseAuthGuard somehow, but without any success. I think there should be an easy solution for it, but I didn't find in any documentation. I will be thanksful for any answer.
you can run functions in the right injection context with the old setup that you had
const result = TestBed.runInInjectionContext(() => inverseAuthGuard());