我有以下代码
login(user: string, pass: string): Observable<User> {
const subject = new Subject<User>();
this.authApi.authTokenPost(user, pass)
.subscribe((token: OAuthAccessToken) => {
this.tokenService.save(token);
this.userApi.fetch()
.subscribe((user: User) => {
subject.next(user);
});
}) // removed error handling for brevity
return subject;
}
当然,问题是我需要两个api调用,所以那时候我通过创建一个新主题并将其返回来解决了这个问题。
现在我正在编写功能测试。.
const user: User = {id: '1234'};
const authApi = jasmine.createSpyObj('AuthApi', ['authTokenPost']);
const tokenService = jasmine.createSpyObj('TokenService', ['save']);
const userApi = jasmine.createSpyObj('UserService', ['fetch']);
beforeEach(() => {
authApi.authTokenPost.and.returnValue(of(oauthAccessToken));
userService.fetch.and.returnValue(of(user));
authenticationService = new AuthService(authApi, tokenService, userApi);
});
it('should login', (done) => {
authService.login('user', 'pass')
.subscribe((user2) => {
expect(user2).toEqual(user);
done();
})
});
问题在于,由于存在模拟,订阅会立即被调用,因此subject.next(user)
甚至会在返回主题之前被调用。.
有人知道解决这个问题的好方法吗?
答案 0 :(得分:0)
我找到了解决方法:
authApi.authTokenPost.and.returnValue(of(oauthAccessToken).pipe(delay(0)));
通过将任何模拟可观察对象延迟甚至0微秒,调用将变得异步,因此在返回主题之后执行。