简体   繁体   中英

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.

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())

I mock classmethods like this:

def raiser(*args, **kwargs):
    raise forms.ValidationError('foo')
with mock.patch.object(mylib.Commands, 'my_class_method', classmethod(raiser)):
    response=self.admin_client.get(url, data=dict(term='+1000'))
from mock import *

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, m):

        return m.method()

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

    print User().run(mock)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM