I have a celery retry task that I would like to test that it retries until successful. Using mock's side_effect, I can fail it for a set number of executions and then passing None
, clear the side effect. However, the method the task is calling doesn't execute at that point, it just doesn't have an exception. Is there a way to clear the side effect, and still have the method being mocked execute as normal?
I can test that it is called 'x' number of times (ie. repeat until successful) and then in a separate test, assert it does what is supposed to, but was wondering if there was a way to do both in one test.
tasks.py:
import celery
@celery.task(max_retries=None)
def task():
print "HERE"
try:
do_something("TASK")
except Exception as exc:
print exc
raise task.retry(exc=exc)
def do_something(msg):
print msg
Test:
import ....
class TaskTests(test.TestCase):
@mock.patch('tasks.do_something')
def test_will_retry_until_successful(self, action):
action.side_effect = [Exception("First"), Exception("Second"), Exception("Third"), None]
tasks.task.delay()
self.assert.... [stuff about task]
Results:
fails three times and then "succeeds" but do_something()
never prints.
action.call_count
equals 4.
I would like to see that the blank line following the last 'HERE' would be print of 'TASK'.
-------------------- >> begin captured stdout << ---------------------
HERE
First
HERE
Second
HERE
Third
HERE
--------------------- >> end captured stdout << ----------------------
do_something()
. Mocking a method doesn't then call the original, with our without side effects. – Manning