我在其他单元测试中遇到了丢失的<router-outlet>
消息,但为了得到一个很好的隔离示例,我创建了一个AuthGuard,用于检查用户是否已登录以执行某些操作。
这是代码:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (!this.authService.isLoggedIn()) {
this.router.navigate(['/login']);
return false;
}
return true;
}
现在我想为此编写单元测试。
这是我开始考试的方式:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{
path: 'login',
component: DummyComponent
}
])
],
declarations: [
DummyComponent
],
providers: [
AuthGuardService,
{
provide: AuthService,
useClass: MockAuthService
}
]
});
});
我创建了一个什么都不做的DummyComponent。
现在我的考试。假设服务返回false并触发this.router.navigate(['/login'])
:
it('should not let users pass when not logged in', (): void => {
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
});
这会抛出一个异常&#34;无法找到要加载的主要插座&#34;。
显然,我可以使用toThrow()
代替toBe(false)
,但这似乎不是一个非常明智的解决方案。由于我在这里测试服务,因此没有模板可以放置<router-outlet>
标记。我可以模拟路由器并创建自己的导航功能,但那么RouterTestingModule的意义何在?也许你甚至想检查导航是否有效。
答案 0 :(得分:43)
我可以模拟路由器并创建自己的导航功能,但那么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']);
这就是通常应该编写单元测试的方式。为了尝试测试任何实际的真实导航,这可能属于端到端测试的范畴。
答案 1 :(得分:2)
it(`editTemplate() should navigate to template build module with query params`, inject(
[Router],
(router: Router) => {
let id = 25;
spyOn(router, "navigate").and.stub();
router.navigate(["/template-builder"], {
queryParams: { templateId: id }
});
expect(router.navigate).toHaveBeenCalledWith(["/template-builder"], {
queryParams: { templateId: id }
});
}
));
答案 2 :(得分:0)
如果您想在不模拟路由器的情况下测试路由器,则可以将其注入测试中,然后直接在此处进行导航方法的监视。 .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']);
}));
});
答案 3 :(得分:0)
这对我有用
describe('navigateExample', () => {
it('navigate Example', () => {
const routerstub: Router = TestBed.get(Router);
spyOn(routerstub, 'navigate');
component.navigateExample();
});
});