I have the below Python==3.8
code, where I:
unittest.mock.patch
as a decoratorpatch(..., 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. How can I get the patched_Bar
arg to be passed in?
I know the below workaround exists, using with
, but I prefer not to do this, as it's less clean in my opinion.
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. 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.
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:
@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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.