【发布时间】:2019-07-29 10:46:33
【问题描述】:
考虑以下服务示例
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);
});
});
});
测试的目的是检查资源缓存是否有效。但我注意到的是,如果我替换以下 sn-p
service.isGranted('dashboard').subscribe();
service.isGranted('dashboard').subscribe();
简单
service.isGranted('dashboard');
service.isGranted('dashboard');
测试仍然有效,我是 RxJS 和大理石测试的新手,但据我所知,Observable 在订阅之前不应该工作。
问题 - 为什么它是双向的?
【问题讨论】:
-
您不是在测试是否创建了 Observable 链。您只是在测试是否调用了
userService.getCurrentUser,并且每次调用isGranted时都会调用它。所以这与 RxJS 无关。 -
为什么
userService.getCurrentUser在没有订阅订阅的情况下被执行?正如我从 RxJS 文档中得到的那样,计算只发生在每个订阅的观察者身上 -
与 RxJS 无关。当您调用
isGranted时,您调用该方法,就像任何其他 JavaScript 代码中的任何其他方法一样。 -
@martin 你能提供一个这个测试应该是什么样子的例子吗?谢谢
标签: angular unit-testing rxjs observable jasmine-marbles