6

I'm using MagicMock with Python 2.7 to mock objects. One of the classes that I'm mocking has properties, one of which can raise a TypeError in some cases.

I would like to mock that behavior, but I can't figure out how:

  • del my_mock.my_property will cause an AttributeError if my_property is accessed, but I need a TypeError.
  • my_mock.my_property = MagicMock(side_effect=TypeError) causes a TypeError when my_property is called, but not when it's merely accessed.

How would I do that?

zneak
  • 134,922
  • 42
  • 253
  • 328
  • Just an idea: 2nd option + `my_mock.my_property = property(my_mock.my_property)` – Klaus D. May 13 '17 at 03:40
  • Maybe make the property a class that defines a [```__delattr__```](https://docs.python.org/3/reference/datamodel.html#object.__delattr__) method which changes its behavior when deleted. – wwii May 13 '17 at 03:45
  • Our maybe it's more accurate to say, define a ```__delattr__``` method for the mock object that will change the behavior of the property when it is deleted. – wwii May 13 '17 at 03:50
  • Our make the property a [descriptor](https://docs.python.org/3/howto/descriptor.html) that does something similar when deleted. – wwii May 13 '17 at 03:59

1 Answers1

7

You can use PropertyMock for this purpose:

import mock

class A(object):

    @property
    def prop(self):
        pass

a = A()
type(a).prop = mock.PropertyMock(side_effect=TypeError)

If you now access a.prop it'll raise a TypeError.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
  • 1
    That looks like what I need, I'll check on Monday. Can I set that on a MagicMock instance as well? – zneak May 14 '17 at 06:21
  • This is fine, except if you want to raise an AttributeError with a custom message, `side_effect=AttributeError('something')`. Then the side_effect is completely ignored. – fulv Jul 09 '21 at 17:36
  • See also: https://stackoverflow.com/questions/18236123/python-propertymock-side-effect-with-attributeerror-and-valueerror – fulv Jul 09 '21 at 20:28