代码之家  ›  专栏  ›  技术社区  ›  ca9163d9

如何嘲笑和测试装饰师?

  •  0
  • ca9163d9  · 技术社区  · 5 年前

    import third_party_lib
    import functools
    
    class MyDecorator:
        def __init__(self, ....):
            self.third_party_lib = ThirdPartyLib(....) # will create a 3rd party instance
    
        def __call__(self, ...):
            def decorator(f):
                @functools.wraps(f)
                def wrap(*arg, **kwargs):
                    result = f(*arg, **kwargs)
                    # ....
                    a = self.third_party_lib.send(value=result).get()
                    # ....
                    return result
                return wrap
            return decorator
    

    我需要创建一个单元测试来断言 third_party_lib.send() 如果函数由装饰器修饰,则调用。理想情况下,还要确保测试函数的结果传递给函数。

    decorator = MyDecorator(....)
    
    @decorator(....)
    def test_func():
        ret = ...
        return ret # ret should be passed to `third_party_lib.send()`
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   MrBean Bremen    5 年前

    如果要验证thirdparty函数是否正确调用,可以模拟它并检查是否使用正确的参数调用了mock。作为 ThirdPartyLib

    from unittest import mock
    
    @mock.patch('third_party_lib.ThirdPartyLib')
    def test_my_decorator(mocked_lib):
        decorator = MyDecorator()
    
        @decorator()
        def example_func():
            return 42
    
        example_func()
        mocked_lib.return_value.send.assert_called_once_with(value=42)
    

    如果在更多测试中需要修饰函数,可以将其包装在函数中:

    def decorated_func():
        decorator = MyDecorator()
    
        @decorator()
        def example_func():
            return 42
    
        return example_func
    
    @mock.patch('third_party_lib.ThirdPartyLib')
    def test_my_decorator(mocked_lib):
        decorated_func()()
        mocked_lib.return_value.send.assert_called_once_with(value=42)