4

I want to mock a class method's output, which is called by a function defined in a different module. For example:

class_module.py

class my_class:
    def __init__(self, user):
        self.user = user

    def my_method(self):
        return [1,2,3]
    
    def other_methods(self):
        other_func(self.user)
        return "something I do not really want to mock"

function_module.py

from class_module import my_class

def my_fun():
    user = "me"
    foo = my_class(user)
    foo.other_methods()
    return foo.my_method()

test.py

@patch("function_module.my_class")
def test_my_fun(class_mock):
    class_mock.return_value.my_method.return_value = []
    bar = my_fun()

    assert bar == []

However, I am getting an AssertionError saying that [1,2,3] != []. So I guess the mock is never happening on the method I want. Can somebody explain how to do it? And why is this happening?

EDIT

Actually, the implementation shown does not work because the test is starting an entirely separate process. Therefore, no function could be mocked. Sorry for my misconception

Miguel Wang
  • 183
  • 1
  • 12
  • You don't patch a single method, replace the class `@patch("function_module.my_class")` then see e.g. https://stackoverflow.com/a/38199345/3001761. – jonrsharpe Dec 24 '20 at 12:56
  • Thanks @jonrsharpe, I tried the other answer you provided. However, I still get the same issue. I updated my question to be more similar to my code – Miguel Wang Dec 24 '20 at 14:35
  • Your code works for me, the test passes locally. – hoefling Dec 24 '20 at 23:19

1 Answers1

4

patch.object allows patching a specific method of a class.

class_module.py

class MyClass:
    def __init__(self, user):
        self.user = user

    def my_method(self):
        return [1, 2, 3]

    def other_methods(self):
        return "anything"

function_module.py

from class_module import MyClass


def my_fun():
    user = "me"
    foo = MyClass(user)
    assert foo.other_methods() == "anything"
    return foo.my_method()

test_my_func.py

from unittest.mock import patch

from class_module import MyClass
from function_module import my_fun


@patch.object(MyClass, "my_method")
def test_my_fun(my_method):
    # given
    any_value = [99, 98, 97]
    my_method.return_value = any_value

    # when
    result = my_fun()

    # then
    assert result == any_value

With these files, pytest test_my_func.py passes successfully.