node-retry retry.operation is being called only once with jest.fn promise reject mocks
mario128mex opened this issue · 1 comments
Hi I have the following code
retryer.js
const retry = require('retry');
const retryer = async (call, options) =>
new Promise((resolve, reject) => {
const { retries: maxRetries } = options
const operation = retry.operation(options)
operation.attempt(async currentAttempt => {
try {
const response = await call()
resolve(response)
} catch (err) {
if (currentAttempt === maxRetries) {
console.error('max amount of calls reached, aborting')
return reject(err)
}
console.error('failed call number: ', currentAttempt);
operation.retry(err)
}
})
})
module.exports = retryer;
then I run this code which send a 404 on purpose
main.js
const axios = require('axios');
const retryer = require('./retryer')
const url = 'https://pokeapi.co/api/v2'
const makeCall = (resource) => {
return axios({
method: 'get',
url: url + resource
})
}
const main = async () => {
const retryerOptions = {
retries: 5,
minTimeout: 1 * 1000,
maxTimeout: 5 * 1000
}
console.log(`making call to ${url} ...`);
const response = await retryer(() => makeCall('/pokemons'), retryerOptions)
console.log('my data', response.data);
console.log('finishing..');
}
main()
the retryer behaves as expected
but in my tests when I pass a mocked function that always returns a rejected promise, the retryer only do one call and then exits, why is this?
retryer.test.js
const retry = require('../retryer.js')
const APICallRetryerOptions = {
retries: 5,
minTimeout: 1000,
maxTimeout: 5000
}
describe('node-retry test issue', () => {
it('should throw and error when the max amount of attempts is reached', async () => {
const mockAxiosError = {
isAxiosError: true,
config: {
url: 'bad-site.com',
method: 'get'
},
response: {
status: 500,
statusText: 'some weird error',
data: {
Error: 'Mock error!'
}
}
}
const mockApiCall = jest
.fn()
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
retry(() => mockApiCall(), APICallRetryerOptions)
expect(mockApiCall).toHaveBeenCalledTimes(5)
})
})
the above code, as I said before, calls mockAPICall once and then exits, I've tried to debug the test to see why that happens but I could figure it out, also I've done some research but I couldn't find a similar issue
I also tried to change mockAPICall
declaration to const mockApiCall = jest.fn(() => Promise.reject(mockAxiosError))
but still getting just one call
can you point out what I'm doing wrong?
Thanks!
I just found out the issue, I needed to await the retry call on my test here
describe('node-retry test issue', () => {
it('should throw and error when the max amount of attempts is reached', async () => {
const mockAxiosError = {
isAxiosError: true,
config: {
url: 'bad-site.com',
method: 'get'
},
response: {
status: 500,
statusText: 'some weird error',
data: {
Error: 'Mock error!'
}
}
}
const mockApiCall = jest
.fn()
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
.mockRejectedValueOnce(mockAxiosError)
try {
await retry(() => mockApiCall(), APICallRetryerOptions)
} catch (err) {
expect(err.isAxiosError).toBeTruthy()
expect(err.response.data.Error).toEqual('Mock error!')
}
expect(mockApiCall).toHaveBeenCalledTimes(5)
})
})