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
相关产品推荐
相关产品推荐

