如何使用模拟将一个方法替换为不同的方法

问题描述 投票:0回答:2
# 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

python unit-testing mocking
2个回答
1
投票

我将其添加为第二个答案只是为了澄清我在评论中的含义。另外,由于问题是关于

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
也会指向这里的原始对象。


0
投票

根据要求,这是一个小例子。µ 它并没有完全回答这个问题,因为它使用 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
© www.soinside.com 2019 - 2024. All rights reserved.