I have the following code
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;
}
The problem of course is that I need two api calls, so back then I solved it by creating a new subject and returning that.
Now I'm writing the functional test..
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();
})
});
The problem is that because of the mocks, the subscribe is called immediately, and therefore the subject.next(user)
is called BEFORE the subject is even returned..
Does anyone know a good way around this?
I found a solution:
authApi.authTokenPost.and.returnValue(of(oauthAccessToken).pipe(delay(0)));
By delaying any of the mock observables even for 0 microseconds, the call becomes async and therefore executes after returning the subject.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.