【问题标题】:Get patch'd object with use of unittest.mock's patch decorator and new使用 unittest.mock 的补丁装饰器和 new 获取补丁对象
【发布时间】:2021-12-20 09:24:08
【问题描述】:

我有以下Python==3.8 代码,其中我:

  • 使用unittest.mock.patch作为装饰器
  • 执行patch(..., new=...):
from unittest.mock import patch

class Foo:
    pass

class Bar:
    pass

@patch(__name__ + f".Foo", new=Bar)
def test_foo(patched_Bar) -> None:
    _ = 0  # Do stuff

目前,这不会运行,因为没有提供 patched_Bar 参数。我怎样才能让patched_Bar arg 被传入?

我知道存在以下解决方法,使用 with,但我不想这样做,因为我认为它不太干净。

def test_foo2() -> None:
    with patch(__name__ + f".Foo", new=Bar) as patched_Bar:
        _ = 0  # Do stuff

【问题讨论】:

    标签: python monkeypatching python-unittest.mock


    【解决方案1】:

    这不是必需的,因为您已经有了修补的类,例如Bar 在你的情况下。如果您使用上下文管理器,您会得到相同的结果,如您所见:

    def test_foo() -> None:
        with patch(f"{__name__}.Foo", new=Bar) as patched_Bar:
            assert patched_bar == Bar
    

    您可能正在考虑获取Bar 的实例,但这不起作用,因为该实例将仅在测试中创建。

    与默认模拟的区别在于,您可以将return_value 设置为模拟类,并且该类的每个实例化都会为您提供相同的实例:

    @patch(f"{__name__}.Foo")
    def test_foo(patched_foo) -> None:
        foo1 = Foo()
        foo2 = Foo()
        assert patched_foo.return_value == foo1 == foo2
        assert isinstance(foo1, MagicMock)
    

    虽然使用不是模拟的替换类,但这是行不通的:

    @patch(f"{__name__}.Foo", Bar)
    def test_foo() -> None:
        foo1 = Foo()
        foo2 = Foo()
        assert foo1 != foo2
        assert isinstance(foo1, Bar)
    
    

    【讨论】:

      猜你喜欢
      • 2017-01-31
      • 2019-09-12
      • 2021-11-21
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 2022-12-09
      相关资源
      最近更新 更多