如何使用茉莉花单位测试来结合Angular2的后卫方法



很抱歉提出此类问题。但是我找不到任何博客或YouTube教程编写Canactivate Guard文件测试。在官方文档中也没有提到任何内容。

任何帮助都将不胜感激。

,因为没有人回答我的问题,所以我要粘贴代码片段,以帮助可能得到这种情况的人。

Sampleloggedin.guard.ts

import {Injectable} from '@angular/core';
import {Router, CanActivate} from '@angular/router';
import {StorageService} from '../storage.service';
@Injectable()
export class LoggedInGuard implements CanActivate {
    constructor(private router: Router, private storageService: StorageService) {
    }
    /**Overriding canActivate to guard routes
     *
     * This method returns true if the user is not logged in
     * @returns {boolean}
     */
    canActivate() {
        if (this.storageService.isLoggedIn) {
            return true;
        } else {
            this.router.navigate(['home']);
            return false;
        }
    }
}

sampleloggedin.guard.spec.ts

import {TestBed, async} from '@angular/core/testing';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import {CommonModule} from '@angular/common';
import 'rxjs/Rx';
import 'rxjs/add/observable/throw';
import {Router} from '@angular/router';
import 'rxjs/add/operator/map';
import {LoggedInGuard} from './loggedin.guard';
import {StorageService} from '../storage.service';
import {CookieService} from 'angular2-cookie/core';
describe('Logged in guard should', () => {
    let loggedInGuard: LoggedInGuard;
    let storageService: StorageService;
    let router = {
        navigate: jasmine.createSpy('navigate')
    };
    // async beforeEach
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [FormsModule, CommonModule, HttpModule],
            providers: [LoggedInGuard, StorageService, CookieService,
                {provide: Router, useValue: router}
            ]
        })
            .compileComponents(); // compile template and css
    }));
    // synchronous beforeEach
    beforeEach(() => {
        loggedInGuard = TestBed.get(LoggedInGuard);
        storageService = TestBed.get(StorageService);
    });
    it('be able to hit route when user is logged in', () => {
        storageService.isLoggedIn = true;
        expect(loggedInGuard.canActivate()).toBe(true);
    });
    it('not be able to hit route when user is not logged in', () => {
        storageService.isLoggedIn = false;
        expect(loggedInGuard.canActivate()).toBe(false);
    });
});

这个问题很旧 - 但是当我自己想自己找到一些详细的单元测试文档时,我只是想把我的方法放在这里。通常,如果我的后卫/服务/组件中有依赖性/我认为应该嘲笑这些依赖项,而不是应该使用真正的服务。由于这些服务不是我们想要在警卫的单位测试中测试的服务 - 我们只想测试后卫。因此,这是一个通用的例子

import { MyGuard } from './path/to/your/guard';
import { TestBed } from '@angular/core/testing';
import { finalize } from 'rxjs/operators';
describe('MyGuard Test', () => {
    const createMockRoute = (id: string) => {
    return {
      params: { id: id }
    } as any;
  };
  const createMockRouteState = () => null;
  let guard: MyGuard;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        MyGuard,
      ]
    });
    guard = TestBed.get(MyGuard);
  });
  it('should not be able to activate invalid route', done => {
    const route = createMockRoute(null);
    const state = createMockRouteState();
    const res$ = guard.canActivate(route, state);
    res$.pipe(finalize(done)).subscribe(res => expect(res).toBeFalsy());
  });
});

这是我在您的特定情况下会做的(应该与Angular 6一起使用,Canactivate也应采用2个参数):

import { LoggedInGuard } from './loggedin.guard';
import { TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { StorageService } from '../storage.service';
describe('LoggedInGuard', () => {
  let guard: LoggedInGuard;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        LoggedInGuard,
        { provide: Router, useClass: { navigate: () => null } },
        { provide: StorageService, useClass: { } }
      ]
    });
    guard = TestBed.get(LoggedInGuard);
  });
  it('should not be able to activate when logged out', () => {
    const storageService = TestBed.get(StorageService);
    storageService.isLoggedIn = false;
    const res = guard.canActivate(null, null);
    expect(res).toBeFalsy();
  });
  it('should be able to activate when logged in', () => {
    const storageService = TestBed.get(StorageService);
    storageService.isLoggedIn = true;
    const res = guard.canActivate(null, null);
    expect(res).toBeTruthy();
  });
});

如果您的后卫是异步的,则可以通过异步测试对其进行测试:

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import { Observable, of } from 'rxjs';
describe('MyGuard', () => {
  let guard: MyGuard;
  let service: MyAsyncService;
  // async beforeEach
  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
      ],
      providers: [
        MyGuard,
        MyAsyncService,
      ],
    });
  }));
  // synchronous beforeEach
  beforeEach(() => {
    guard = TestBed.inject(MyGuard);
    service = TestBed.inject(MyAsyncService);
  });
  it('should allow if service reports as allowed', (done) => {
    service.canFoo = (): Observable<boolean> => of(true);
    guard.canActivate(null, null).subscribe({
      next: (allowed: boolean) => {
        expect(allowed).toBeTrue();
        done();
      },
      error: err => {
        fail(err);
      },
    });
  });
  it('should reject if service reports as not allowed', () => {
    service.canFoo = (): Observable<boolean> => of(false);
    guard.canActivate(null, null).subscribe({
      next: (allowed: boolean) => {
        expect(allowed).toBeFalse();
        done();
      },
      error: err => {
        fail(err);
      },
    });
  });
});

最新更新