As the unittest.mock documentation points out:
Because of the way mock attributes are stored you can’t directly attach a PropertyMock to a mock object. Instead you can attach it to the mock type object
However, I'm encountering cases where I want to mock out multiple values of a property on multiple class instances within a single test.
For example, say I have a TimeSlot
class with an availability
property:
class TimeSlot:
@property
def availability(self):
# Run a complex DB query to determine availability
... and I have a helper class that sorts a list of TimeSlot
instances by availability
:
from unittest.mock import Mock
from app.helpers import sort_slots
from app.models import TimeSlot
def test_sort_slots_reorders_by_descending_availability():
slot_a = TimeSlot()
slot_a.availability = Mock(return_value=0.1) # BOOM!
slot_b = TimeSlot()
slot_b.availability = Mock(return_value=0.2)
slots = [slot_a, slot_b]
assert sort_slots(slots) == [slot_b, slot_a]
Running this test raises an error when I try to assign a Mock (or PropertyMock) to the availability
property:
AttributeError: can't set attribute
Is there any way to mock property return values per instance of a Python class?
If not, is there a different way I should be approaching writing unit tests like this?
Thanks!