这个问题已经很老了——但是当我现在试图自己寻找一些详细的单元测试文档时,我只想把我的方法放在这里。一般来说,如果我的警卫/服务/组件/我认为这些都应该被嘲笑而不是真正的服务应该被使用。由于这些服务不是我们想要在守卫的单元测试中测试的 - 我们只想测试守卫。
因此,这是一个通用示例,我将如何为返回 observable 的守卫执行此操作:
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();
});
});