【问题标题】:Asserting an exception generated by a @propertyname.setter断言由 @propertyname.setter 生成的异常
【发布时间】:2019-12-14 05:37:17
【问题描述】:

源代码

我有一些代码要求我调用一个属性设置器来测试一个类的锁定功能是否正常工作(该类的一些函数是async,要求在它们执行期间设置一个挂锁布尔值) .如果已为实例设置了锁,则已编写 setter 以引发 RuntimeError

代码如下:

    @filename.setter
    def filename(self, value):
        if not self.__padlock:
            self.__filename = value
        else:
            self.__events.on_error("data_store is locked.  you should be awaiting safe_unlock if you wish to "
                                  "change the source.")

正如您在此处看到的,如果 self.__padlockTrue,则会引发 RuntimeError。尝试使用 python unittest 断言设置器时会出现问题。

问题

unittest 似乎缺少断言属性设置器是否引发异常所需的功能。

尝试使用assertRaises 显然不起作用:

    # Non-working concept
    self.assertRaises(RuntimeError, my_object.filename, "testfile.txt")

问题

如何断言类的属性设置器将在 python unittest.TestCase 方法中引发给定异常?

【问题讨论】:

  • 非常好的问题:“如何断言类的属性设置器会在 python unittest.TestCase 方法中引发给定的异常?”知道 unittest 缺少断言天气所需的功能或属性设置器会引发异常。

标签: python unit-testing properties assert testcase


【解决方案1】:

您需要通过赋值实际调用 setter。这很简单,只要您使用assertRaises 作为上下文管理器。

with self.assertRaises(RuntimeError):
    my_object.filename = "testfile.txt"

如果你不能这样做,你将不得不回退到一个明确的try 语句(这很棘手,因为你需要分别处理“无异常”和“RuntimeError 以外的异常”。

try:
    my_object.filename = "testfile.txt"
except RuntimeError:
    pass
except Exception:
    raise AssertionError("something other than RuntimeError")
else:
    raise AssertionError("no RuntimeError")

或(更多)显式调用setter:

self.assertRaises(RuntimeError, setattr, myobject, 'filename', 'testfile.txt')

或者更糟糕的是,显式调用 setter:

self.assertRaises(RuntimeError, type(myobject).filename.fset, myobject, 'testfile.txt')

换句话说,为上下文管理器欢呼三声!

【讨论】:

  • 甚至包括 setattr 调用!非常完整的解决方案。谢谢你。 :-)
  • 对于那些观看的人,我绝对不推荐使用 self.assertIsInstance(myobject, MyObjectClass) 隐含的显式转换(出于正当理由标记为更糟),这很有效。我在这里选择了(更多)解决方案,它有效。
  • 出于好奇,您为什么不使用with 语句?
  • with context 非常适合检查多个语句是否存在同一个异常。我只需要检查一个。没有看到需要在一次性场景中使用。打开带有上下文的内容本质上也比直接调用要慢,因此对我来说这是一个按需使用的提议。
  • 做了一些测试后出现错误。 DeprecationWarning: callable is None 。如果使用我的首选选项,避免此警告的正确语法是 self.assertRaises(RuntimeError, setattr, myobject, 'filename', 'testfile.txt') 您不得在对 assertRaises 的调用中调用可调用对象,而是让该方法为您调用它。
【解决方案2】:

您可以像这样使用setattr 方法:

self.assertRaises(ValueError, setattr, p, "name", None)

在上面的示例中,我们将尝试将p.name 设置为等于None 并检查是否存在ValueError

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 2017-12-14
    • 2023-03-15
    相关资源
    最近更新 更多