如何对Angular的canActivate进行单元测试?

Raj*_*ngh 3 angular-ui-router angular angular6 angular7

如何测试canActivateangular 的函数,该函数返回一个函数,该函数又返回一个boolean值?。

我尝试创建ActivatedrouterSnapshotand 的对象routerStateSnapshot并将其传递给canActivate函数,但这没有帮助。

export class AuthGuard implements CanActivate {
constructor(
private authService: AuthenticationService,
private loginService: LoginService,
private router: Router
) {}

canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> 
| boolean {
return this.checkLogin(state.url);
}

checkLogin(url: string): boolean {
    if (this.authService.isLoggedIn()) {  return true; }

// Store the attempted URL for redirecting
this.loginService.redirectUrl = url;

// Navigate to the login page with extras
this.router.navigate(['/login']);
return false;
 }
}
Run Code Online (Sandbox Code Playgroud)

自从checklogin回归以来true,我希望这种情况发生。但我不知道从哪里开始?

dmc*_*dle 5

有很多方法可以做到这一点。我会建议类似以下内容。只是为了展示一些多样性,我用一个类模拟了一个服务,用一个 spyObject 模拟了另一个服务。

这是建议的代码:

class LoginMock implements Partial<LoginService> {
    redirectUrl: string;
}

describe('AuthGuard', () => {

    let authGuard: AuthGuard;
    let loginService: LoginMock;
    const routerMock = jasmine.createSpyObj('Router', ['navigate']);
    const authMock = jasmine.createSpyObj('AuthenticationService', ['isLoggedIn']);

    beforeEach(() => {
        loginService = new LoginMock();
        authGuard = new AuthGuard(authMock, loginService, routerMock);
    });

    it('should be createable', () => expect(authGuard).toBeTruthy());

    it('should return true for canActivate() and not set loginService.redirectUrl when isLoggedIn === true', ()=> {
        authMock.isLoggedIn.and.returnValue(true);
        const result = authGuard.canActivate(new ActivatedRouteSnapshot(), <RouterStateSnapshot>{url: 'testUrl'});
        expect(result).toBe(true);
        expect(loginService.redirectUrl).toBeUndefined();
    });

    it('should return false for canActivate() and set loginService.redirectUrl when isLoggedIn === false', ()=> {
        authMock.isLoggedIn.and.returnValue(false);
        const result = authGuard.canActivate(new ActivatedRouteSnapshot(), <RouterStateSnapshot>{url: 'testUrl'});
        expect(result).toBe(false);
        expect(loginService.redirectUrl).toEqual('testUrl');
    });

});
Run Code Online (Sandbox Code Playgroud)

我已经为你把它放在了一个Stackblitz中。随意将其分叉到您自己的 Stackblitz 环境中并进行修改。

祝你好运。:)