I have the following code that I\'m trying to test:
great_report.py
from retry import retry
@retry((ReportNotReadyException), tries=3, delay=10, bac
There is no way to change decorators parameters after load the module. Decorators decorate the original function and change it at the module load time.
First I would like encourage you to change your design a little to make it more testable.
If you extract the body of get_link()
method test the new method and trust retry
decorator you will obtain your goal.
If you don't want add a new method to your class you can use a config module that store variables that you use when call retry
decorator. After that you can use two different module for testing and production.
The last way is the hacking way where you replace retry.api.__retry_internal
by a your version that invoke the original one by changing just the variables:
import unittest
from unittest.mock import *
from pd import get_link, ReportNotReadyException
import retry
orig_retry_internal = retry.api.__retry_internal
def _force_retry_params(new_tries=-1, new_delay=0, new_max_delay=None, new_backoff=1, new_jitter=0):
def my_retry_internals(f, exceptions, tries, delay, max_delay, backoff, jitter, logger):
# call original __retry_internal by new parameters
return orig_retry_internal(f, exceptions, tries=new_tries, delay=new_delay, max_delay=new_max_delay,
backoff=new_backoff, jitter=new_jitter, logger=logger)
return my_retry_internals
class MyTestCase(unittest.TestCase):
@patch("retry.api.__retry_internal", side_effect=_force_retry_params(new_tries=1))
def test_something(self, m_retry):
self.assertRaises(ReportNotReadyException, get_link, None)
IMHO you should use that hacking solution only if you are with the back on the wall and you have no chance to redesign you code to make it more testable. The internal function/class/method can change without notice and your test can be difficult to maintain in the future.
As hinted here, an easy way to prevent the actual sleeping is by patching the time.sleep
function. Here is the code that did that for me:
@patch('time.sleep', side_effect = lambda _: None)