使用unittest测试作业失败

Len*_*nna 12 python unit-testing properties variable-assignment assertraises

我的一个属性是一个属性,其中setter调用验证函数,如果新值无效则引发异常:

pos.offset = 0
# @offset.setter calls validate(offset=0)
# PositionError: Offset may not be 0.
Run Code Online (Sandbox Code Playgroud)

我正在尝试添加测试以确保此操作失败.但是,我无法弄清楚如何让assertRaises与赋值一起工作.

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

self.assertRaises(PositionError, pos.offset, 0)
# TypeError: 'int' object is not callable
Run Code Online (Sandbox Code Playgroud)

我尝试过的其他形式是无效的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
Run Code Online (Sandbox Code Playgroud)

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

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

Wil*_*uck 16

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

with self.assertRaises(PositionError):
    pos.offset = 0
Run Code Online (Sandbox Code Playgroud)

这个用法可以在unittest docs中找到.

虽然这在Python 2.6中不可用,并且对你不起作用(我刚看到你的注释),但我认为值得包含在答案中,因为对于python 2.7+来说这可能是更清晰的方法.


Len*_*nna 7

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

self.assertRaises(PositionError, setattr, pos, "offset", 0)
# ... ok
Run Code Online (Sandbox Code Playgroud)

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