2

I have a unit test that patches the default value of a Django DateTimeField to a known value. This test passes fine, until I introduce a test that creates a ModelForm based on the same model, at which point the original test starts to fail:

Failure
Traceback (most recent call last):
  File "test_example.py", line 36, in test_init_date_missing
    self.assertEqual(actual.event_datetime, test_dt)
AssertionError: datetime.datetime(2019, 2, 27, 12, 20, 25, 69409) != datetime.datetime(2019, 2, 10, 10, 10, 10)

The test passes when run independently of the other, but as soon as I try to run both in the same suite, it fails. It's as if the patching is failing as soon as the form is instantiated in another test.

This example code demonstrates the issue:

from datetime import datetime
from unittest import mock

from django import forms
from django.test import TestCase
from django.db import models
from django.utils import timezone


class MyExampleModel(models.Model):
    event_datetime = models.DateTimeField(default=timezone.now)


class MyExampleForm(forms.ModelForm):
    class Meta:
        model = MyExampleModel
        fields = ['event_datetime']


class ExampleTest(TestCase):
    def test_init_date_missing(self):
        """Tests that date is set automatically when not provided"""
        # Little bit of magic to mock the default value of a Django Field
        # Taken from https://stackoverflow.com/questions/18924869/mocking-default-timezone-now-for-unit-tests
        test_dt = datetime(2019, 2, 10, 10, 10, 10)
        event_datetime_field = MyExampleModel._meta.get_field('event_datetime')
        mock_tznow = mock.MagicMock(return_value=test_dt)

        with mock.patch.object(event_datetime_field, 'default', mock_tznow):
            actual = MyExampleModel()

        self.assertEqual(actual.event_datetime, test_dt)
        actual.save()  # The proof is in the pudding, will it actually save?


class ExampleFormTest(TestCase):
    def test_form(self):
        """Commenting out the below line causes ExampleTest.test_init_date_missing to pass
        Uncommmenting causes ExampleTest.test_init_date_missing to fail"""
        MyExampleForm()

Why is this happening? And is there anything I can do about it to get these tests playing nice together?

chrisbunney
  • 5,819
  • 7
  • 48
  • 67

0 Answers0