【问题标题】:Python: calling stop on mock patch class decoratorPython:在模拟补丁类装饰器上调用停止
【发布时间】:2014-08-01 22:44:48
【问题描述】:

Mock documentation 描述了一种简单而优雅的方法,可以将补丁应用到 TestCase 中的所有测试方法:

@patch('foo.bar')
@patch('foo.baz')
@patch('foo.quux')
@patch('foo.narf')
class FooTest(TestCase):

    def test_foo(self, bar, baz, quux, narf):
        """ foo """
        self.assertTrue(False) 

但是,我在使用此方法时遇到的一个问题是,如果我想在其中一种测试方法中的一个补丁上调用 stop(),似乎无论如何都无法获得参考到 patcher 对象——传递给方法的唯一东西是模拟对象,在本例中为 barbazquuxnarf

我发现解决此问题的唯一方法是移至 Mock 文档中描述的模式,其中修补程序被实例化并在 TestCasesetUp 方法内启动并在 tearDown 内停止方法。这符合我的目的,但增加了很多额外的样板,并且不像类装饰器方法那样优雅。

还有其他方法可以解决这个问题吗?

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    1

    假设你想在一个方法中临时恢复foo.narffoo.narf 在修饰函数的上下文中是一个 MagicMock 对象。这个对象有一个_mock_wraps 属性,当调用模拟时会调用它!所以在你的模块顶部,_narf = foo.narf,在你的测试用例中,foo.narf._mock_wraps = _narf

    问题在于,这只会传递给真正的函数,而不是真正将其交换回来,这意味着某些测试用例会失败(例如,如果它们依赖于函数对象实际上是“自身”)。如果您的模拟具有其他属性,那 可能 会干扰(我没有测试太多),因为对 _mock_wraps() 的直通调用位于首先考虑模拟的其他属性的方法的底部.

    2

    patch() 装饰器涉及将每个patcher(每个方法的单独副本)添加到名为patchings 的列表中,该列表是方法本身的字段。 IE。您可以通过self.test_foo.patchings 访问此列表,然后通过查找您想要的列表。

    然而,start()stop() 在你使用 patch() 作为装饰器时实际上并没有被调用,一旦你开始接触并改变它,行为就会变得棘手。所以我写了这个上下文管理器。

    class unpatch:
        def __init__(self, name, method):
            compare = patch(name)
            self.patcher = next((
                p for p in method.patchings
                if p.target == compare.getter()
                and p.attribute == compare.attribute
            ), None)
            if self.patcher is None:
                raise ValueError(name)
    
        def __enter__(self):
            self.patcher.__exit__()
    
        def __exit__(self, *exc_info):
            self.patcher.__enter__()
    

    在您的测试用例中,您可以这样使用它:

    with unpatch('foo.narf', self.test_foo):
        foo.narf()
    

    免责声明:这是黑客行为。

    【讨论】:

      猜你喜欢
      • 2022-12-09
      • 2017-01-31
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      相关资源
      最近更新 更多