如何编写截止日期验证单元测试?测试DateField/DateTimeField验证逻辑
如何为DateField/DateTimeField的截止日期验证编写单元测试
针对你提供的Task模型中due_date的验证逻辑(截止日期不能早于time_stamp),这里介绍几种编写单元测试的方法:
原模型代码
from django.db import models from django.forms import ValidationError class Task(models.Model): title = models.CharField(max_length=100, blank=True) desc = models.TextField(blank=True) time_stamp = models.DateField(auto_now_add=True, null=True, blank=True) due_date = models.DateField(null=True, blank=True) # logic for due_date def clean(self): super().clean() if self.due_date < self.time_stamp: raise ValidationError("Due date must be greater than current date")
方法1:直接调用模型的clean()方法测试
这种方法最直接,手动创建Task实例并设置日期字段,调用clean()后验证是否抛出预期异常。
from django.test import TestCase from django.core.exceptions import ValidationError from datetime import date, timedelta from .models import Task class TaskModelValidationTest(TestCase): def test_due_date_before_time_stamp_raises_error(self): # 创建Task实例,手动设置time_stamp为昨天,due_date为前天 task = Task( time_stamp=date.today() - timedelta(days=1), due_date=date.today() - timedelta(days=2) ) # 断言调用clean()会抛出ValidationError,且消息匹配 with self.assertRaises(ValidationError) as context: task.clean() self.assertEqual( str(context.exception), "['Due date must be greater than current date']" ) def test_due_date_after_time_stamp_passes_validation(self): # 设置due_date晚于time_stamp,验证不抛出异常 task = Task( time_stamp=date.today() - timedelta(days=1), due_date=date.today() + timedelta(days=1) ) # clean()不抛出异常则测试通过 task.clean()
方法2:通过ModelForm测试验证逻辑
模型的clean()方法会在表单验证时自动触发,用ModelForm可以模拟实际业务中的验证场景。
from django.test import TestCase from django.core.exceptions import ValidationError from django.forms import ModelForm from datetime import date, timedelta from .models import Task class TaskForm(ModelForm): class Meta: model = Task fields = ['title', 'desc', 'time_stamp', 'due_date'] class TaskFormValidationTest(TestCase): def test_form_invalid_when_due_date_before_time_stamp(self): # 构造不符合验证规则的表单数据 form_data = { 'time_stamp': date.today() - timedelta(days=1), 'due_date': date.today() - timedelta(days=2) } form = TaskForm(data=form_data) # 断言表单无效 self.assertFalse(form.is_valid()) # 验证错误消息是否正确 self.assertEqual( form.errors['__all__'][0], "Due date must be greater than current date" ) def test_form_valid_when_due_date_after_time_stamp(self): form_data = { 'time_stamp': date.today() - timedelta(days=1), 'due_date': date.today() + timedelta(days=1) } form = TaskForm(data=form_data) # 断言表单有效 self.assertTrue(form.is_valid())
方法3:测试模型保存时的验证逻辑
调用模型的save()方法时,Django会自动执行full_clean()(包含clean()),可以直接测试保存操作是否触发验证异常。
from django.test import TestCase from django.core.exceptions import ValidationError from datetime import date, timedelta from .models import Task class TaskSaveValidationTest(TestCase): def test_save_task_with_invalid_due_date_raises_error(self): task = Task( time_stamp=date.today() - timedelta(days=1), due_date=date.today() - timedelta(days=2) ) # 断言保存时抛出ValidationError with self.assertRaises(ValidationError) as context: task.save() self.assertEqual( str(context.exception), "['Due date must be greater than current date']" ) def test_save_task_with_valid_due_date_succeeds(self): task = Task( time_stamp=date.today() - timedelta(days=1), due_date=date.today() + timedelta(days=1) ) # 保存成功则无异常抛出,验证记录已存入数据库 task.save() self.assertIsNotNone(task.pk)
内容的提问来源于stack exchange,提问作者Shivʌm Singh Ʀathod
相关产品推荐
相关产品推荐

