【问题标题】:How to unittest a ValidationError and assert the correct code is used?如何对 ValidationError 进行单元测试并断言使用了正确的代码?
【发布时间】:2020-11-02 18:12:39
【问题描述】:

我有一个带有ValidationError 约束的模型:

class MyModel(models.Model)
    title = models.CharField()
      
    def clean(self):
        error_dict = {}
        if self.title='invalid_title':
                 error_dict['title'] = ValidationError(
                         'Title is invalid', code='invalid_title_code')
        
        if error_dict:
                 raise ValidationError(error_dict)

我想对这个ValidationError 进行单元测试,但是如何测试code 是否正确?例如:

def test_title_invalid(self):

     with self.assertRaises(ValidationError) as cm: 
          MyModel.objects.create(title='invalid_title')
     
     exception = cm.exception

     # Test the key exists
     self.assertTrue(hasattr(exception, 'error_dict'))
     self.assertIn('title', exception.error_dict)

     # Test the message exists
     self.assertIn('Title is invalid', exception.messages)

     # Test the code exists
     self.assertIn('invalid_title_code', exception.code)

这一切正常,直到 self.assertIn('invalid_title_code', exception.code),这导致 AttributeError 声明 'ValidationError' object has no attribute 'code'

django.core.exceptions.ValidationError 的django 源中,如果您传递dict 对象,则不会添加代码属性:

class ValidationError(Exception):
    """An error while validating data."""
    def __init__(self, message, code=None, params=None):
        super().__init__(message, code, params)

        if isinstance(message, dict):
            self.error_dict = {}
            for field, messages in message.items():
                if not isinstance(messages, ValidationError):
                    messages = ValidationError(messages)
                self.error_dict[field] = messages.error_list
 
        else:
            self.message = message
            self.code = code
            self.params = params
            self.error_list = [self]

这是问题的原因吗?

【问题讨论】:

    标签: python django python-unittest django-testing django-tests


    【解决方案1】:

    这是一个嵌套异常,您可以通过以下方式访问它:

    exception = cm.exception
    self.assertTrue(hasattr(exception, 'error_dict'))
    self.assertIn('title', exception.error_dict)
    title_exceptions = exception.error_dict['title']
    self.assertEqual(1, len(title_exceptions))
    title_exception = title_exceptions[0]
    self.assertEqual('invalid_title_code', title_exception.code)

    【讨论】:

    • title_exceptions[0] 提供KeyErrortitle_exceptionsrepr{'title': [ValidationError(['Title is invalid'])]},好像没有嵌套?
    • @alias51: 抱歉出错了,应该是title_exceptions = exception.error_dict['title']
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多