[英]How to test Angular2's router.navigate?
我在其他单元测试中遇到了丢失<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);
});
这将引发“找不到要加载的主要出口”的异常。 显然我可以使用toThrow()
而不是toBe(false)
,但这似乎不是一个非常明智的解决方案。 由于我在这里测试服务,因此没有可以放置<router-outlet>
标记的模板。 我可以模拟路由器并制作自己的导航功能,但是RouterTestingModule 的意义何在? 也许您甚至想检查导航是否有效。
我可以模拟路由器并制作自己的导航功能,但是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']);
这就是单元测试通常应该如何编写的。 为了尝试测试任何实际的真实导航,这可能属于端到端测试的范畴。
如果你想在不模拟的情况下测试路由器,你可以将它注入到你的测试中,然后直接监视那里的导航方法。 .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']);
}));
});
这对我有用
describe('navigateExample', () => {
it('navigate Example', () => {
const routerstub: Router = TestBed.get(Router);
spyOn(routerstub, 'navigate');
component.navigateExample();
});
});
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 }
});
}
));
我想出了类似的东西:
describe('TestComponent', () => {
let component: TestComponent;
let router: Router;
let fixture: ComponentFixture<TestComponent>;
const routerSpy = jasmine.createSpyObj('Router', ['navigate']); // create a router spy
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
declarations: [TestComponent],
providers: [
{ provide: Router, useValue: routerSpy } // use routerSpy against Router
],
}).compileComponents();
}));
beforeEach(() => {
router = TestBed.inject(Router); // get instance of router
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it(`should navigate to 'home' page`, () => {
component.navigateToHome(); // call router.navigate
const spy = router.navigate as jasmine.Spy; // create the navigate spy
const navArgs = spy.calls.first().args[0]; // get the spy values
expect(navArgs[0]).toBe('/home');
});
});
受角度文档的启发: https ://angular.io/guide/testing-components-scenarios#routing-component
我是单元测试 angular/javascript 应用程序的新手。 我需要一种方法来模拟(或监视)我的单元测试。 以下行是从 Experimenter 借来的,对我帮助很大!
const routerSpy = jasmine.createSpyObj('Router', ['navigate']); // 创建一个路由器间谍
我想说我不知道我可以用 Jasmine 做到这一点。 使用上面的那一行,我可以在该对象上创建一个间谍,并验证它是使用正确的路由值调用的。
这是一种进行单元测试的好方法,无需测试平台和围绕设置测试模块的所有仪式。 它也很棒,因为它仍然允许我拥有一个假路由器对象,而无需存根所有参数、方法等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.