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

Django测试中如何正确断言psycopg2.errors.NotNullViolation异常

问题原因

Django的save()方法不会在触发数据库约束时返回False,而是会直接抛出对应的数据库异常。你当前的测试逻辑假设save()执行失败会返回布尔值False,但实际代码执行到stevie.save()时直接抛出了NotNullViolation异常,没有走到断言步骤,因此测试直接报错而非通过。

调整方案

使用Django测试内置的assertRaises上下文管理器,捕获预期抛出的异常即可:

from psycopg2.errors import NotNullViolation
# 也可以导入Django封装的通用异常:from django.db.utils import IntegrityError

def test_tutor_fname_notnull(self):
    '''
    first_name的NOT NULL约束生效时测试通过,缺少first_name时数据不会存入数据库且抛出异常
    '''
    stevie = Tutors(last_name='wonder',email='sboywonder@gmail.com',birth_day='1990-01-02') 
    with self.assertRaises(NotNullViolation): # 若使用IntegrityError,此处替换为对应类即可
        stevie.save()

以上代码逻辑为:只要save()操作抛出了预期的NotNullViolation异常,断言就会判定通过,正好匹配你要验证数据库约束生效的需求。

额外可选优化

如果你希望在校验阶段就捕获空值问题,不需要等到请求数据库,可以给模型的first_name字段添加blank=False参数,之后测试时可以先调用stevie.full_clean()触发模型层校验,捕获ValidationError即可,这种方式执行效率更高。

内容的提问来源于stack exchange,提问作者jarjarbinks99

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 18:54:03