python retry with tenacity, disable `wait` for unittest

后端 未结 4 1851
无人共我
无人共我 2021-01-17 16:57

I am using the tenacity library to use its @retry decorator.

I am using this to make a function which makes a HTTP-request \"repeat\" multiple times in

相关标签:
4条回答
  • 2021-01-17 17:37

    You can use unittest.mock module to mock some elements of tentacity library. In your case all decorators you use are classes e.g. retry is a decorator class defined here. So it might be little bit tricky, but I think trying to

    mock.patch('tentacity.wait.wait_random_exponential.__call__', ...)
    

    may help.

    0 讨论(0)
  • 2021-01-17 17:48

    mock the base class wait func with:

    mock.patch('tenacity.BaseRetrying.wait', side_effect=lambda *args, **kwargs: 0)
    

    it always not wait

    0 讨论(0)
  • 2021-01-17 17:49

    Thanks to discussion here, I found an elegant way to do this based on code from @steveb:

    from tenacity import retry, stop_after_attempt, wait_exponential
    
    
    @retry(reraise=True, stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=4, max=10))
    def do_something_flaky(succeed):
        print('Doing something flaky')
        if not succeed:
            print('Failed!')
            raise Exception('Failed!')
    

    And tests:

    from unittest import TestCase, mock, skip
    from main import do_something_flaky
    
    
    class TestFlakyRetry(TestCase):
        def test_succeeds_instantly(self):
            try:
                do_something_flaky(True)
            except Exception:
                self.fail('Flaky function should not have failed.')
    
        def test_raises_exception_immediately_with_direct_mocking(self):
            do_something_flaky.retry.sleep = mock.Mock()
            with self.assertRaises(Exception):
                do_something_flaky(False)
    
        def test_raises_exception_immediately_with_indirect_mocking(self):
            with mock.patch('main.do_something_flaky.retry.sleep'):
                with self.assertRaises(Exception):
                    do_something_flaky(False)
    
        @skip('Takes way too long to run!')
        def test_raises_exception_after_full_retry_period(self):
            with self.assertRaises(Exception):
                do_something_flaky(False)
    
    0 讨论(0)
  • 2021-01-17 17:59

    The solution came from the maintainer of tenacity himself in this Github issue: https://github.com/jd/tenacity/issues/106

    You can simply change the wait function temporarily for your unit test:

    from tenacity import wait_none
    
    func.retry.wait = wait_none()
    
    0 讨论(0)
提交回复
热议问题