13

我的属性之一是设置器调用验证函数的属性,如果新值无效,该函数会引发异常:

pos.offset = 0
# @offset.setter calls validate(offset=0)
# PositionError: Offset may not be 0.

我正在尝试添加测试以确保失败。但是,我不知道如何让 assertRaises 处理作业。

assertRaises 的正常语法需要一个方法,而不是属性/属性:

self.assertRaises(PositionError, pos.offset, 0)
# TypeError: 'int' object is not callable

我尝试过的其他形式是无效的 Python:

self.assertRaises(PositionError, pos.offset = 0)
# SyntaxError: Keyword can't be an expression
self.assertRaises(PositionError, lambda: pos.offset = 0)
# SyntaxError: lambda cannot contain assignment

如何测试分配给属性的失败?

注意:Python 2.6,我知道 unittest 在 2.7 中有一些新特性

4

2 回答 2

17

当您想使用unittest来测试代码块中发生的异常而不仅仅是函数调用时,您可以将assertRaises其用作上下文管理器:

with self.assertRaises(PositionError):
    pos.offset = 0

这种用法可以在unittest docs中找到。

虽然这在 Python 2.6 中不可用,并且对您不起作用(我刚刚看到您的注释),但我认为值得将其包含在答案中,因为这可能是对 python 2.7+ 执行此操作的更清晰的方法。

于 2012-08-17T16:56:57.197 回答
8

在 Python 2.7 之前,您想使用setattr(object, name, value) ( doc )。这允许您为属性设置值。

self.assertRaises(PositionError, setattr, pos, "offset", 0)
# ... ok

这应该总是有效的,因为如果属性是一个属性并因此“秘密”调用一个函数,它必须在一个类中。我不认为标准分配会失败(尽管右侧的表达式x = 1/0可能会失败,即)。

于 2012-08-17T16:27:13.823 回答