# actual code
class x:
def func(self):
print("actual func")
def other_func(self):
print("do not touch me!")
# test method
class mockX():
def func(self):
print("mocked func")
我想测试使用
x
的代码。我想模拟 x.func
,而 x
的所有其他方法应该保持不变。仅使用像 mock.return_value = "some value"
这样的东西来模拟太复杂了,这就是我创建 mockX.func
的原因。
如何使用
x.func
将
mockX.func
替换为
unittest.mock
我将其添加为第二个答案只是为了澄清我在评论中的含义。另外,由于问题是关于
unittest
我不会在这里使用 pytest
,尽管我同意使用 pytest
这可以移动到固定装置。
只要你不需要模拟类本身,你就可以模拟函数:
from unittest import mock
class X:
def func(self):
print("actual func")
def other_func(self):
print("do not touch me!")
class MockedX:
def func(self):
print("mocked func")
# the patch string has to be adapted if the class lives in another module,
# this is just for illustration
@mock.patch(f"{__name__}.X.func", MockedX.func)
def test_x():
x = X()
x.func() # prints "mocked func"
x.other_func() # prints "do not touch me"
请注意,在这种情况下,
self
仍然指向原始对象。
您甚至不需要为模拟对象单独的类 - 编写一个模拟函数就足够了:
def mocked_func(self):
print("mocked func")
@mock.patch(f"{__name__}.X.func", mocked_func)
def test_x():
x = X()
x.func() # prints "mocked func"
x.other_func() # prints "do not touch me"
self
也会指向这里的原始对象。
根据要求,这是一个小例子。µ 它并没有完全回答这个问题,因为它使用 pytest 而不仅仅是 unittest。但它可以提供一些想法。
mrbean-bremen的评论也可以提供帮助
import pytest
from pytest_mock import MockerFixture
class x:
def __init__(self) -> None:
print("Init X")
def func(self):
print("actual func")
def other_func(self):
print("do not touch me!")
def overload_func():
print("mocked func")
@pytest.fixture()
def mockX(mocker: MockerFixture) -> x:
x_fixture = x()
mocker.patch.object(x_fixture, "func", wraps=overload_func)
return x_fixture
def test_run(mockX: x):
mockX.func()
mockX.other_func()
assert True == True