You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写截止日期验证单元测试?测试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:07:05