要测试Angular的canActivate()异步函数,可以使用Angular的测试工具,如Jasmine和Karma。
下面是一个示例:
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { AuthGuard } from './auth.guard';
describe('AuthGuard', () => {
let guard: AuthGuard;
let authService: AuthService;
let router: Router;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [AuthGuard, AuthService]
});
guard = TestBed.inject(AuthGuard);
authService = TestBed.inject(AuthService);
router = TestBed.inject(Router);
});
it('should allow navigation if user is authenticated', async () => {
// Mock the isAuthenticated() method of AuthService to return true
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
const route: ActivatedRouteSnapshot = {} as ActivatedRouteSnapshot;
const state: RouterStateSnapshot = {} as RouterStateSnapshot;
const canActivate = await guard.canActivate(route, state);
expect(canActivate).toBe(true);
});
it('should block navigation if user is not authenticated', async () => {
// Mock the isAuthenticated() method of AuthService to return false
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(false));
const route: ActivatedRouteSnapshot = {} as ActivatedRouteSnapshot;
const state: RouterStateSnapshot = {} as RouterStateSnapshot;
const canActivate = await guard.canActivate(route, state);
expect(canActivate).toBe(false);
expect(router.navigate).toHaveBeenCalledWith(['/login']);
});
});
在这个示例中,我们首先导入了需要的测试工具和依赖项,然后使用TestBed配置测试环境。我们使用了RouterTestingModule来模拟路由器,并注入了AuthGuard和AuthService。
在第一个测试用例中,我们使用spyOn()来模拟AuthService的isAuthenticated()方法,并返回一个解决的Promise,表示用户已经进行了身份验证。然后,我们创建一个空的ActivatedRouteSnapshot和RouterStateSnapshot,并调用canActivate()方法来测试它是否允许导航。最后,我们断言canActivate()返回的结果应该为true。
在第二个测试用例中,我们使用spyOn()来模拟AuthService的isAuthenticated()方法,并返回一个解决的Promise,表示用户尚未进行身份验证。然后,我们创建一个空的ActivatedRouteSnapshot和RouterStateSnapshot,并调用canActivate()方法来测试它是否阻止导航。最后,我们断言canActivate()返回的结果应该为false,并且router.navigate()方法应该被调用,并传递了一个指向登录页面的数组参数。