当我试图对我的警卫进行单元测试时,它以奇怪的方式失败。如果我尝试订阅canActivate
返回的Observable,测试会冻结,最终Karma会因超时而断开连接:
警告[HeadlessChrome 0.0.0(Mac OS X 10.13.0)]:已断开连接(1 因为10000毫秒没有消息。
防护本身在应用程序中运行良好,它只会导致测试中出现问题。提高超时值并不能解决问题。
不崩溃:
it('...', async(() => {
guard.canActivate(
{ params: { id: 'a' } as any } as ActivatedRouteSnapshot
);
}));
此确实崩溃(只有更改正在添加.subscribe()
):
it('...', async(() => {
guard.canActivate(
{ params: { id: 'a' } as any } as ActivatedRouteSnapshot
).subscribe();
}));
这个确实也会崩溃,使用Jasmine完成的回调:
it('...', done => {
guard.canActivate(
{ params: { id: 'a' } as any } as ActivatedRouteSnapshot
).subscribe(x => done());
});
测试来源:
describe('Guard', () => {
let store: Store<fromRoot.State>;
let guard: Guard;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([]),
StoreModule.forRoot(reducers)
],
providers: [
Guard
]
});
store = TestBed.get(Store);
guard = TestBed.get(Guard);
});
it('...', async(() => {
guard.canActivate(
{ params: { id: 'a' } as any } as ActivatedRouteSnapshot
).subscribe();
expect(1).toBe(1);
}));
});
警卫来源:
@Injectable()
export class Guard implements CanActivate {
constructor(
private store: Store<fromRoot.State>,
private router: Router
) {}
getFromStoreOrApi(id: string): Observable<any> {
return this.store.select(fromRoot.selectState)
.do(state => {
if (!state.entities[id]) {
this.store.dispatch(new actions.Get(id));
}
});
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
return this.getFromStoreOrApi(route.params.id)
.switchMap(() => Observable.of(true))
.catch(() => Observable.of(false));
}
}
答案 0 :(得分:1)
我不认为卡玛会崩溃。它正在等待Observable完成。
it('...', async(() => {
guard.canActivate(
{ params: { id: 'a' } as any } as ActivatedRouteSnapshot
).take(1).subscribe();
}));
在第一个发布值后,添加take(1)
或first()
运算符以自动完成。