简体   繁体   English

使用 unittest.mock 的补丁装饰器和 new 获取补丁对象

[英]Get patch'd object with use of unittest.mock's patch decorator and new

I have the below Python==3.8 code, where I:我有以下Python==3.8代码,其中我:

  • Use unittest.mock.patch as a decorator使用unittest.mock.patch作为装饰器
  • Preform a patch(..., new=...) :预制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

Currently, this doesn't run, as the patched_Bar argument is not supplied.目前,这不会运行,因为没有提供patched_Bar参数。 How can I get the patched_Bar arg to be passed in?如何让patched_Bar arg 传入?

I know the below workaround exists, using with , but I prefer not to do this, as it's less clean in my opinion.我知道存在以下解决方法,使用with ,但我不想这样做,因为在我看来它不太干净。

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

This is not needed, because you already have the patched class, eg Bar in your case.这不是必需的,因为您已经有了修补类,例如Bar在您的情况下。 You get the same if you use the context manager, as you can see:如果您使用上下文管理器,您会得到相同的结果,如您所见:

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

May be you are thinking about getting an instance of Bar instead, but that cannot work, because the instance will be created only inside the test.可能您正在考虑获取Bar的实例,但这行不通,因为该实例只会在测试中创建。

The difference with a default mock is that you can set return_value to the mocked class, and each instantiation of the class will get you the same instance:与默认模拟的不同之处在于您可以将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)

while with a replacement class which is not a mock this won't work:虽然使用不是模拟的替换类,这将不起作用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM