Reputation: 19913
I have the below method in my NestJS project:
getAccessToken(): Observable < string > {
return this.httpService.post(`${url}/oauth2/token`, params).pipe(
retryWhen((errors) =>
errors.pipe(
delay(1000),
take(5),
(e) =>
concat(
e,
throwError(
`Error retrieving access token. Tried 5 times.`
)
)
)
),
catchError((err) => {
this.loggerService.error(err);
throw err;
}),
map((res) => res.data),
map((data) => data.access_token)
);
}
The above code will call the API. If successful, it will return access_token
, if fails it tries up to 5 times, and if not successful after 5 times, it will throw an exception.
Now I want to write 3 unit tests,
Success when the API is not throwing error and return an access token
Fails 6 times
Fails 2 times and return access token
it('should return access_token', async () => {
const response: AxiosResponse = {
data: {
access_token: 'token1'
},
status: 200,
statusText: 'OK',
headers: {},
config: {}
};
const post = jest
.spyOn(httpService, 'post')
.mockImplementationOnce(() => of(response));
try {
const token = await service.getAccessToken().toPromise();
expect(token).toBe('token1');
} catch (err) {
expect(true).toBeFalsy();
}
});
it('should retry and fails', async () => {
const err: AxiosError = {
config: {},
code: '500',
name: '',
message: '',
response: {
data: {},
status: 500,
statusText: '',
headers: {},
config: {}
},
isAxiosError: true,
toJSON: () => null
};
const post = jest
.spyOn(httpService, 'post')
.mockImplementationOnce(() => throwError(err));
try {
await service.getAccessToken().toPromise();
expect(true).toBeFalsy();
} catch (err) {
expect(err).toBe(
'Error retrieving access token. Tried 5 times.'
);
}
});
However, I can't figure out how to write the test for the 3rd.
Upvotes: 0
Views: 2096
Reputation: 19913
I found the solution in case someone else has same problem
it('should retry and return access token', async () => {
const response: AxiosResponse = {
data: {
access_token: 'token1'
},
status: 200,
statusText: 'OK',
headers: {},
config: {}
};
const err: AxiosError = {
config: {},
code: '500',
name: '',
message: '',
response: {
data: {},
status: 500,
statusText: '',
headers: {},
config: {}
},
isAxiosError: true,
toJSON: () => null
};
let retried = 0;
const post = jest
.spyOn(httpService, 'post')
.mockImplementationOnce(() => {
return new Observable((s) => {
if (retried <= 1) {
retried += 1;
s.error(err);
} else {
s.next(response);
s.complete()
}
});
});
try {
const token = await service.getAccessToken().toPromise();
expect(token).toBe('token1');
} catch (err) {
expect(true).toBeFalsy();
}
expect(post).toHaveBeenCalled();
expect(post).toHaveBeenCalledTimes(1);
});
Upvotes: 1