Home > Blockchain >  How to replace a method with a different method using mock
How to replace a method with a different method using mock

Time:05-25

# 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")

I would like to test code which is using x. I would like to mock x.func, while all other methods of x should stay the same. The mocking is to complicated to just use something like mock.return_value = "some value", which is why I created mockX.func.

How can I replace x.func with mockX.func using unittest.mock

CodePudding user response:

As requested, here is a small example.µ It doesn't totally answer the question because it uses pytest and not only unittest. But it can give some ideas.

The comment of mrbean-bremen can also help

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

CodePudding user response:

I'm adding this as a second answer just to clarify what I meant in the comment. Also, as the question was about unittest I won't use pytest here, though I agree that with pytest this could be moved to a fixture.

As long as you don't need to mock the class itself, you can just mock the function:

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"

Note that self still points to the orignal object in this case.

  • Related