我的一个属性是一个属性,其中setter调用验证函数,如果新值无效,则会引发异常:
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
中有一些新功能答案 0 :(得分:15)
如果要使用unittest
来测试代码块中发生异常而不仅仅是函数调用,可以使用assertRaises
作为上下文管理器:
with self.assertRaises(PositionError):
pos.offset = 0
此用法可在unittest docs。
中找到虽然这在Python 2.6中不可用,并且对你不起作用(我刚刚看到你的注释),但我认为值得包含在答案中,因为它可能是为python 2.7做的更明智的方法+。
答案 1 :(得分:7)
在Python 2.7之前,您想使用setattr(object, name, value)
(doc)。这允许您为属性设置值。
self.assertRaises(PositionError, setattr, pos, "offset", 0)
# ... ok
这应该始终有效,因为如果属性是属性,那么"偷偷地"调用一个函数,它必须在一个类中。我不认为标准作业会失败(尽管右侧的表达式可能会失败,即x = 1/0
)。