Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a property

I'm asking how to mock a class property in a unit test using Python 3. I've tried the following, which makes sense for me following the docs, but it doesn't work:

foo.py:

class Foo():
    @property
    def bar(self):
        return 'foobar'


def test_foo_bar(mocker):
    foo = Foo()
    mocker.patch.object(foo, 'bar', new_callable=mocker.PropertyMock)
    print(foo.bar)

I've installed pytest and pytest_mock and run the test like this:

pytest foo.py

I got the following error:

>       setattr(self.target, self.attribute, new_attr)
E       AttributeError: can't set attribute

/usr/lib/python3.5/unittest/mock.py:1312: AttributeError

My expectation would be that the test runs without errors.

like image 822
hek2mgl Avatar asked Mar 09 '17 20:03

hek2mgl


People also ask

How do you set a mock object property?

You can set the mock object property to the value returned by the mock object method. To achieve this, specify separate behaviors for the method and the property. You can specify one behavior at a time. For more information about mock object behavior, see Specify Mock Object Behavior.

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.

How do you set a value to a mocked object?

To solve your problem of knowing whether the setName() method was called in your code with the specified value use the Mockito verify method. For example: verify(mockedFoo, times(1)). setName("test");

Which of the methods of the mock class allows to verify that we have performed a get and set operations on property?

Property Setter Set operations are mocked using a special set entry point which is Mock. ArrangeSet(lambda) . Property set mocking is useful when you want to make sure or to verify that a particular property is set with an expected value.


1 Answers

The property mechanism relies on the property attribute being defined on the object's class. You can't create a "property like" method or attribute on a single instance of a class (for a better understanding, read about Python's descriptor protocol)

Therefore you have to apply the patch to your class - you can use the with statement so that the class is properly restored after your test:

def test_foo_bar(mock):
    foo = Foo()
    with mock.patch(__name__ + "Foo.bar", new=mocker.PropertyMock)
        print(foo.bar)
like image 187
jsbueno Avatar answered Oct 09 '22 01:10

jsbueno