测试装饰器参数

时间:2018-09-17 17:41:09

标签: python unit-testing python-decorators

我有一个装饰器,它接受两个参数callbackonerror,它们都应该像这样可调用

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')

这一定是更好的方法,不是吗?

1 个答案:

答案 0 :(得分:1)

正如Leo K所评论的那样,有一种更简单的方法来测试某些代码是否在测试中引发异常,尽管不同的库的拼写方式略有不同。在event中,您可以将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