Bar*_*art 29 unit-testing angular2-testing angular
我<router-outlet>在其他单元测试中遇到了丢失的消息,但是为了得到一个很好的隔离示例,我创建了一个AuthGuard,用于检查用户是否已登录以执行某些操作.
这是代码:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (!this.authService.isLoggedIn()) {
this.router.navigate(['/login']);
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
现在我想为此编写一个单元测试.
这就是我开始测试的方式:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{
path: 'login',
component: DummyComponent
}
])
],
declarations: [
DummyComponent
],
providers: [
AuthGuardService,
{
provide: AuthService,
useClass: MockAuthService
}
]
});
});
Run Code Online (Sandbox Code Playgroud)
我创建了一个什么都不做的DummyComponent.现在我的考试.假设服务返回false并触发this.router.navigate(['/login']):
it('should not let users pass when not logged in', (): void => {
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
});
Run Code Online (Sandbox Code Playgroud)
这将引发"无法找到要加载的主要插座"的异常.显然我可以使用toThrow()而不是toBe(false),但这似乎不是一个非常明智的解决方案.由于我在这里测试服务,因此没有模板可以放置<router-outlet>标签.我可以模拟路由器并创建自己的导航功能,但那么RouterTestingModule有什么意义呢?也许你甚至想检查导航是否有效.
Pau*_*tha 51
我可以模拟路由器并创建自己的导航功能,但那么RouterTestingModule有什么意义呢?也许你甚至想检查导航是否有效.
没有真正的意义.如果他只是auth后卫的单元测试,那么只需模拟并监视模拟,检查它的navigate方法是否被login参数调用
let router = {
navigate: jasmine.createSpy('navigate')
}
{ provide: Router, useValue: router }
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
expect(router.navigate).toHaveBeenCalledWith(['/login']);
Run Code Online (Sandbox Code Playgroud)
这就是通常应该编写单元测试的方法.为了尝试测试任何实际的真实导航,这可能属于端到端测试的范畴.
Chr*_*nam 15
如果你想在不模拟的情况下测试路由器,你可以将它注入你的测试中,然后直接监视导航方法。该.and.stub()将使因此呼叫没有做任何事情。
describe('something that navigates', () => {
it('should navigate', inject([Router], (router: Router) => {
spyOn(router, 'navigate').and.stub();
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
expect(router.navigate).toHaveBeenCalledWith(['/login']);
}));
});
Run Code Online (Sandbox Code Playgroud)