Django Patch Side effect IntegrityError not being raised
<p>I have the following view, which excepts POST requests, and serializes an objects data (a Draftschedule) to create a new copy (a FrozenSchedule):</p>

<pre><code>from reports.tasks import create_frozen_schedule

def freeze_schedule(request, pk):
    """Valid post request will freeze a Draft Schedule serializing its data"""
    client = get_object_or_404(Client, draftschedule=pk)
    try:
        # Serialize data into a FrozenSchedule object
        frozenschedule = create_frozen_schedule(pk, request.user.id)
    except IntegrityError:
        # Warn user if action failed
        messages.warning(request, "A Schedule of this Type already exists")
        return redirect(client.draftschedule)
    else:
        # If Schedule is Frozen successfully
        messages.success(request, "Schedule Frozen")
        return redirect(frozenschedule)
</code></pre>

<p>I'm trying to write a test to assert certain things happen after an IntegrityError is raised. I'm struggling to understand why it's failing, it's not immediately obvious to me where I'm going wrong since I'm fairly inexperienced with mocking / patching.</p>

<p>I've tried to mock the <code>create_frozen_schedule</code> function to raise an IntegrityError when called:</p>

<pre><code>def setUp(self):
    self.url = reverse(
        'reports:draftschedule-freeze',
        args=[self._client.draftschedule.pk]
    )
    super(TestFreezeSchedule, self).setUp()


@patch('reports.tasks.create_frozen_schedule')
def test_freeze_schedule_with_conflict(self, mock_freeze):
    mock_freeze.side_effect = IntegrityError
    with self.assertRaises(IntegrityError):
        self.client.post(self.url)

   # More unit tests following same premise...
</code></pre>

<p>But I end up with the following error:</p>

<pre><code>.......................................................................................F............
======================================================================
FAIL: test_freeze_schedule_with_conflict (reports.tests.test_views.TestFreezeSchedule)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/mock.py", line 1136, in patched
    return func(*args, **keywargs)
  File "/home/jwe/piesup2/reports/tests/test_views.py", line 495, in test_freeze_schedule_with_conflict
    self.client.post(self.url)
AssertionError: IntegrityError not raised

----------------------------------------------------------------------
</code></pre>

<p>Points to note:</p>

<ul>
<li>I'm able to replicate this error outside of tests on my actual Django site.</li>
<li>I've purposely omitted the <code>create_frozen_schedule</code> code since the
serialization is quite long-winded and it's my understanding that the
implementation details shouldn't matter anyway since I'm mocking the
function.</li>
<li><p>The purpose of the IntegrityError itself is to prevent duplicate <code>FrozenSchedule</code> objects, whose Meta class looks as follows: </p>

<pre><code>class Meta:
    # ...
    unique_together = ('client', 'data',)
</code></pre></li>
</ul>

<p>Any ideas why the side effect isn't being raised?</p>

<p>Your view catches IntegrityError and returns a redirect. The client post, which is what your test calls, doesn't raise an error at all.</p>

<p>Rather, you should be testing that the actions in the except block happen: is the warning set, and does the post redirect to the draft schedule instead of the frozen one.</p>

python django mocking