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.
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.
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.
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");
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With