【发布时间】:2020-11-03 06:34:35
【问题描述】:
我正在尝试编写一个单元测试,断言我的嵌套自定义异常是由函数引发的。
以下示例代码通过:
from unittest import TestCase
class MyClass():
class MyException(Exception):
pass
def fail():
raise MyClass.MyException()
class MyTests(TestCase):
def test_throwsException(self):
with self.assertRaises(MyClass.MyException):
fail()
但是,当我的提升代码涉及 try-except 时,我的测试会失败:
from unittest import TestCase
from enum import Enum
class Weekdays(Enum):
MONDAY = 'mon'
TUESDAY = 'tue'
WEDNESDAY = 'wed'
THURSDAY = 'thu'
FRIDAY = 'fri'
class InvalidValue(Exception):
pass
def parse(key: str) -> Weekdays:
try:
return Weekdays(key)
except Exception as e:
raise Weekdays.InvalidValue() from e
class MyTests(TestCase):
def test_throwsException(self):
with self.assertRaises(Weekdays.InvalidValue):
parse('invalid')
它返回以下错误:
E
======================================================================
ERROR: test_throwsException (test_main.MyTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:\PythonCodes\playground\test_main.py", line 25, in test_throwsException
with self.assertRaises(Weekdays.InvalidValue):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\unittest\case.py", line 816, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\unittest\case.py", line 187, in handle
raise TypeError('%s() arg 1 must be %s' %
TypeError: assertRaises() arg 1 must be an exception type or tuple of exception types
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
我不太明白arg 1 must be an exception type 的含义,因为我假设我的自定义异常是异常类型。
为什么第二个版本的 try-except 失败了?
【问题讨论】:
-
你为什么要定义你的异常类inside你的枚举?这使得您从
Weekdays.InvalidValue一个枚举 访问的内容具有该类属性的.value...就像您在枚举上定义的任何其他类属性一样。只需将其从枚举中删除即可。 -
嗯,我明白了!这确实解决了这个问题。似乎枚举类中不能有嵌套类。您可以将此添加为答案,以便我接受吗?顺便说一句,我出于组织目的嵌套了我的自定义异常。
-
嗯,他们可以。但是嵌套一个类并没有什么特别之处,它相当于
my_attribute = SomeClass。一般来说,嵌套类不是 Python 中的常见模式。它确实没有提供太多优势。代码组织的基本单位是module。 -
我最近在 python 中看到了一些关于嵌套类的问题。我认为对于嵌套类的工作方式存在一个普遍的误解,因为它们根本不从它们所在的类继承任何东西。也许有人可以纠正我,但我能看到嵌套类的唯一好处是组织命名空间。然后,当外部类更改属性访问的工作方式时,即使这样也可能会消失。
-
@Aaron 是的,将一个类定义粘贴在另一个类定义的主体中的唯一效果是生成的类对象位于它嵌套的类的命名空间中. 当然,对于元类,各种诡计都可能发生,如上所示。我曾经使用过一次或两次嵌套类,我相信它们在 Django 中使用过(它严重依赖于元类魔法)。但这几乎总是比它的价值更麻烦。如果一个类是“私有的”并且不应该公开,只需将它放在模块级别并使用单下划线,这就是 Pythonic 约定。
标签: python unit-testing exception try-catch