[英]Minimal mock for unit testing angular Router and CanActivate guard
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree} from '@angular/router';
@Injectable({provideIn: 'root'})
export class FooGuard implements CanActivate {
constructor (private readonly router: Router) {}
canActivate (next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<UrlTree> {
const xxx = myMagic(next); // irrelevant app logic that depends on next url only
return (async () => this.router.parseUrl(xxx));
}
}
Trying to find an example of testing code for this piece without a page of extra boilerplate.试图找到一个没有额外样板页面的测试代码示例。 Hopefully can get something closer to 5-6 lines of code per mock.希望每个模拟可以得到接近 5-6 行代码的东西。 Need:需要:
Router
Router
模拟ActivatedSnapshot
ActivatedSnapshot
模拟Take a look at RouterTestingModule .看看RouterTestingModule 。 It's not a six lines of code solution, but a pretty compact one.这不是一个六行代码的解决方案,而是一个非常紧凑的解决方案。 I think it's the best way to test guards and routes:我认为这是测试守卫和路线的最佳方式:
import { Component, Injectable } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from "@angular/router";
import { RouterTestingModule } from '@angular/router/testing';
@Injectable({
providedIn: 'root'
})
export class FooGuard implements CanActivate {
constructor (private readonly router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): UrlTree {
const url = "some/new/url"; // create an url based on next snapshot
return this.router.parseUrl(url);
}
}
@Component({ template: '' })
export class DummyComponent {}
function setup(): {
router: Router
} {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{ path: 'test', component: DummyComponent, canActivate: [ FooGuard ] },
{ path: 'some/new/url', component: DummyComponent }
])
],
declarations: [
DummyComponent
]
});
return {
router: TestBed.get(Router)
};
}
describe(FooGuard.name, () => {
it('should redirect to a new url', async () => {
const { router } = setup();
await router.navigateByUrl('/test');
expect(router.url).toBe('/some/new/url');
})
});
Actually the regular Router.forRoot()
should also work in this case, but RouterTestingModule
must be more suitable for testing.实际上常规的Router.forRoot()
也应该在这种情况下工作,但RouterTestingModule
必须更适合测试。 For example the last one provides custom Location
implementation.例如,最后一个提供自定义Location
实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.