我有一个单元测试,将Django DateTimeField的默认值修补为已知值。此测试通过良好,直到引入基于同一模型创建ModelForm的测试为止,此时原始测试开始失败:
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)
该测试在相互独立运行时通过,但是一旦我尝试在同一套件中同时运行两者,它就会失败。好像在另一个测试中实例化表单后,修补程序就失败了。
此示例代码演示了该问题:
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()
为什么会这样? 为了使这些测试很好地配合,我能做些什么?