title: Mock side effect only X number of times
body: <p>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 <code>None</code>, 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?</p>
  
  <p>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.</p>
  
  <p>tasks.py:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Test:</p>
  
  <pre><code>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]
  </code></pre>
  
  <p>Results:
  fails three times and then "succeeds" but <code>do_something()</code> never prints.
  <code>action.call_count</code> equals 4.
  I would like to see that the blank line following the last 'HERE' would be print of 'TASK'.</p>
  
  <pre><code>-------------------- &gt;&gt; begin captured stdout &lt;&lt; ---------------------
  HERE
  First
  HERE
  Second
  HERE
  Third
  HERE
  
  --------------------- &gt;&gt; end captured stdout &lt;&lt; ----------------------
  </code></pre>