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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With