Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to patch an attribute in an object

The question is how to patch an attribute of an instance within a with statement. I tried with following example which doesn't work. It prints as in the comment.

from mock import patch, PropertyMock

class Foo(object):
    f = {'a': 1}

new_foo = Foo()

with patch.object(new_foo, 'f', new_callable=PropertyMock) as mock:
    mock.return_value = {'b': 2}
    print new_foo.f
    # <PropertyMock name='f' id='4474801232'>
like image 670
Memke Avatar asked Jan 12 '14 11:01

Memke


People also ask

What is patch object in Python?

patch() unittest. mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.

How do you mock a property in Python?

I think the better way is to mock the property as PropertyMock , rather than to mock the __get__ method directly. It is stated in the documentation, search for unittest. mock. PropertyMock : A mock intended to be used as a property, or other descriptor, on a class.

What is MagicMock?

MagicMock. MagicMock objects provide a simple mocking interface that allows you to set the return value or other behavior of the function or object creation call that you patched. This allows you to fully define the behavior of the call and avoid creating real objects, which can be onerous.

How do you mock a list in Python?

Do note that you probably want to pass in a filename, not the directory (unless your test directory is nested under the actual directory you wanted to be used). Your mock configuration replaced sys. argv with a callable object, so only sys. argv() would have produced your [THIS_DIR] list.


2 Answers

There's an example in the documentation. You need to provide the class to patch.object, not the instantiated object.

from mock import patch, PropertyMock

class Foo(object):
    f = {'a': 1}

new_foo = Foo()

with patch.object(Foo, 'f', new_callable=PropertyMock) as mock:
    mock.return_value = {'b': 2}
    print new_foo.f

print new_foo.f

Outputs:

{'b': 2}
{'a': 1}
like image 110
Silfheed Avatar answered Nov 15 '22 14:11

Silfheed


config.py

class myClass(object):
    def __init__(self):
        self.greeting = "hola"

test_first_test.py

from config import myClass

@patch.object(myClass, "greeting", "what up homie")
def test_one(self):
    print(myClass.greeting)

Output:

what up homie

like image 30
Brian Sanchez Avatar answered Nov 15 '22 16:11

Brian Sanchez