Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking a class method that is used via an instance

I'm trying to patch a class method using mock as described in the documentation. The Mock object itself works fine, but its methods don't: For example, their attributes like call_count aren't updated, even though the method_calls attribute of the class Mock object is. More importantly, their return_value attribute is ignored:

class Lib:
    """In my actual program, a module that I import"""
    def method(self):
        return "real"

class User:
    """The class I want to test"""
    def run(self):
        l = Lib()
        return l.method()

with patch("__main__.Lib") as mock:
    #mock.return_value = "bla" # This works
    mock.method.return_value = "mock"
    u = User()
    print(u.run())

>>> 
mock
<MagicMock name='Lib().method()' id='39868624'>

What am I doing wrong here?

EDIT: Passing a class Mock via the constructor doesn't work either, so this is not really related to the patch function.

like image 835
Erik Avatar asked Mar 15 '12 21:03

Erik


People also ask

How do you mock the method of the same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing.

What is a mock instance?

Instance mocking means that a statement like: $obj = new \MyNamespace\Foo; …will actually generate a mock object. This is done by replacing the real class with an instance mock (similar to an alias mock), as with mocking public methods.

Is it possible to call the actual methods after mocking a class?

Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().

Which method is used to create and inject the mocked instances?

@Mock Annotation We can use @Mock to create and inject mocked instances without having to call Mockito.


1 Answers

I have found my error: In order to configure the methods of my mock's instances, I have to use mock().method instead of mock.method.

class Lib:
    """In my actual program, a module that I import"""
    def method(self):
        return "real"

class User:
    """The class I want to test"""
    def run(self):
        l = Lib()
        return l.method()

with patch("__main__.Lib") as mock:
    #mock.return_value = "bla" # This works
    mock().method.return_value = "mock"
    u = User()
    print(u.run())
like image 114
Erik Avatar answered Sep 23 '22 08:09

Erik