Here is a slightly different variation on the aforementioned answers (allowing arguments to be logged during unit test execution while logging args passed):
I had a quick and dirty back off function like like the following (there's probably several libraries to do this better, but I didn't feel like googling - I guess I ended up here anyhow though).
def backoff(retries_left: int = 3, retries_max: int = 3) -> int:
'''
Linear 15 second backoff
'''
sleep_time = (retries_max - retries_left) * 15
if sleep_time > 0:
logging.warning('Retrying in %d seconds...', sleep_time)
time.sleep(sleep_time)
return sleep_time
Here's how I wrote the unit test around the expected values
import unittest
from unittest.mock import patch
import my_app as app
def mock_sleep(sleep_time: int = 0):
'''
Mock the sleep function.
'''
app.logging.info('time.sleep called with %d seconds', sleep_time)
class TestApp(unittest.TestCase):
'''
Test cases for the app module.
'''
@patch('time.sleep', mock_sleep)
def test_backoff(self):
'''
Test the backoff function.
'''
values = {
3: 0,
2: 15,
1: 30,
0: 45
}
for key, value in values.items():
self.assertEqual(
app.backoff(key),
value
)
self.assertEqual(
app.backoff(retries_left=1, retries_max=5),
60
)
Output for the unit tests are like:
2024-05-08 10:06:41,047 WARNING Retrying in 15 seconds...
2024-05-08 10:06:41,047 INFO time.sleep called with 15 seconds
2024-05-08 10:06:41,047 WARNING Retrying in 30 seconds...
2024-05-08 10:06:41,047 INFO time.sleep called with 30 seconds
2024-05-08 10:06:41,047 WARNING Retrying in 45 seconds...
2024-05-08 10:06:41,047 INFO time.sleep called with 45 seconds
2024-05-08 10:06:41,047 WARNING Retrying in 60 seconds...
2024-05-08 10:06:41,047 INFO time.sleep called with 60 seconds
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Taking this a step further I suppose *args
and **kwargs
could be referenced instead of a predefined value like in the above mocked function example.