4

I have class with two class methods. Method A calls method B, processes his response and returns it. Method A is used by other code. I want to mock method B so that method A will call his mocked version just like in example below:

module1.py

class SomethingGetter: # method B - I want to mock it @classmethod def get_something(cls): return 'something' # method A - it should use response of mocked version of method A @classmethod def get_formatted_something(cls): return f'formatted {cls.get_something()}' 

module2.py

from module1 import SomethingGetter # this function should use SomethingGetter with mocked class mehotd def something_printer(): print(SomethingGetter.get_formatted_something()) 

module3.py

from unittest import mock from module1 import SomethingGetter from module2 import something_printer # I want to use this function in test insted of SomethingGetter.get_something def get_something_else(): return SomethingGetter.get_something() + ' else' if __name__ == '__main__': with mock.patch('module2.SomethingGetter', autospec=True) as patched: patched.get_something = get_something_else something_printer() # it prints <MagicMock name='SomethingGetter.get_formatted_something()' id='139753624280704'>; # but I expected that it would print "formatted something else" 

What have I done wrong?

1 Answer 1

1

By patching module2.SomethingGetter, you've also caused get_formatted_something() to be patched.

Instead, you should only patch the get_something() method, storing a reference to the original:

original = SomethingGetter.get_something with mock.patch.object(SomethingGetter, 'get_something', lambda: original() + ' else'): something_printer() 
Sign up to request clarification or add additional context in comments.

2 Comments

I was trying to do it in this way, but it causes exception RecursionError: maximum recursion depth exceeded. It occures because get_something_else uses SomethingGetter.get_something, which should be mocked. I solved this problem by making get_something module function instead of class method. But I want to know is there any solution in which I could remain get_something as class method.
@VasiliyKirstia My mistake, I didn't see that you were calling the original method. I've submitted an edit that I tested and confirmed is working.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.