我有一个装饰器接受两个参数callback
和onerror
,两者都应该是这样的callables
class mydecorator(object):
def __init__(self, callback, onerror=None):
if callable(callback):
self.callback = callback
else:
raise TypeError('Callable expected in "callback" parameter')
self.onerror = onerror
if self.onerror and not callable(self.onerror):
raise TypeError('Callable expected in "onerror" parameter')
def __call__(self, func):
return self.__param__call__(func)
def __param__call__(self, func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
try:
self.callback()
except MyCustomException as e:
if self.onerror:
self.onerror(e.message, e.data)
else:
raise
return result
return wrapper
我想测试我传递一个无效的参数,例如一个不可调用的,它应该提出一个TypeError
使用Python unittest
实现这一目标的最佳方法是什么?我愿意这样做:
def test_non_callable_callback_should_return_type_error(self):
try:
@mydecorator('this_is_not_a_callable')
def my_phony_func():
pass
except TypeError:
# Correctly has raised a TypeError, lets just pass
pass
else:
# It has not raised an TypeError, let's fail
self.fail('TypeError not raised when a non callable passed to callback')
它一定是更好的方式,不是吗?
正如Leo K评论的那样,有一种更简单的方法可以测试某些代码是否会在测试中引发异常,尽管不同的库会略微区分不同的东西。在unittest.TestCase
中,您可以使用self.assertRaises
作为上下文管理器:
def test_non_callable_callback_should_return_type_error(self):
with self.assertRaises(TypeError):
@mydecorator('this_is_not_a_callable')
def my_phony_func():
pass
实际上,通过消除被测试代码的不必要部分,您可以进一步简化操作。因为你期望mydecorator
类在调用它时引发异常(而不是在函数上调用实例时),你可以摆脱虚函数并一起跳过@decorator
语法。 assertRaises
方法甚至可以为您打电话:
def test_non_callable_callback_should_return_type_error(self):
self.assertraises(TypeError, mydecorator, 'this_is_not_a_callable')