请考虑以下服务示例
export class AuthService {
private observableCache: { [key: string]: Observable<boolean> } = {};
private resourceCache: { [key: string]: boolean } = {};
constructor(private userService: UserService) { }
isGranted(resource): Observable<boolean> {
if (this.resourceCache[resource]) {
return of(this.resourceCache[resource]);
}
if (this.observableCache[role]) {
return this.observableCache[role];
}
this.observableCache[resource] = this.userService
.getCurrentUser()
.pipe(map((user: User) => user.canAccess(resource)))
.pipe(share());
return this.observableCache[resource];
}
}
在此服务中,我正在检查是否允许用户查看特定资源。
这就是我要对其进行测试的方式
describe('AuthService', () => {
let service: AuthService;
let userService: any;
beforeEach(() => {
userService = jasmine.createSpyObj('UserService', ['getCurrentUser']);
service = new AuthGuardService(userService);
});
describe('isGranted', () => {
const user: User = {id: 123};
beforeEach(() => {
userService.getCurrentUser.and.returnValue(
hot('-^u', { u: user })
);
});
it('should prove response being cached', () => {
service.isGranted('dashboard').subscribe();
service.isGranted('dashboard').subscribe();
expect(userService.getCurrentUser).toHaveBeenCalledTimes(1);
});
});
});
测试的目的是检查资源缓存是否正常。但是我注意到的是,如果我替换以下代码段
service.isGranted('dashboard').subscribe();
service.isGranted('dashboard').subscribe();
简单
service.isGranted('dashboard');
service.isGranted('dashboard');
该测试仍然有效,我是RxJS和大理石测试的新手,但据我所知,Observable在订阅之前不起作用。
问题-为什么它同时起作用?
答案 0 :(得分:1)
测试所用的代码是异步的,请尝试使用fakeAsync
和tick
来运行它
it('should prove response being cached', fakeAsync(() => {
service.isGranted('dashboard').subscribe();
service.isGranted('dashboard').subscribe();
tick();
expect(userService.getCurrentUser).toHaveBeenCalledTimes(1);
}));
有关https://angular.io/guide/testing#component-with-async-service的更多信息。