问题描述
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));
}
}
试图找到一个没有额外样板页面的测试代码示例.希望每个模拟可以得到接近 5-6 行代码的东西.需要:
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. Need:
- 模拟
Router
- 模拟
ActivatedSnapshot
推荐答案
看一看 RouterTestingModule.这不是一个六行代码的解决方案,而是一个非常紧凑的解决方案.我认为这是测试守卫和路线的最佳方式:
Take a look at 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');
})
});
实际上常规的Router.forRoot()
也应该适用于这种情况,但是RouterTestingModule
必须更适合测试.例如,最后一个提供 custom Location
实现.
Actually the regular Router.forRoot()
should also work in this case, but RouterTestingModule
must be more suitable for testing. For example the last one provides custom Location
implementation.
这篇关于用于单元测试角度路由器和 CanActivate 防护的最小模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!