1

I'm trying to mock a Django property named next_automatic_service_days that returns a list of Date objects. Here is how I do:

@freeze_time("2029-01-01")
def test_create_next_services_on_monday(self):
    today = date.today()

    with patch('restaurants.models.RestaurantParameters._next_automatic_service_days',
               return_value=[today + td(days=i) for i in range(4)]):
         # Call create_next_services method here

On models.py file:

class RestaurantParameters(models.Model):
    class Meta:
        abstract = True

    @cached_property
    def _next_automatic_service_days -> List[date]:
        # ...

    def create_next_services(self):
        for day in self._next_automatic_service_days:
            # We should enter this loop 4 times in the test

The problem is, we never enter the loop. When I use ipdb in create_next_services, I can see _next_automatic_service_days is a magic mock, and the return value is a list of 4 items.

What is wrong with my code? Thanks.

David Dahan
  • 10,576
  • 11
  • 64
  • 137
  • 1
    Have you tried using `PropertyMock` as discussed in [this question](https://stackoverflow.com/q/11836436/3767239) (resp. [this answer](https://stackoverflow.com/a/25424012/3767239))? – a_guest Mar 09 '18 at 15:03
  • Thanks a lot. Just adding `new_callable=PropertyMock` make the whole thing works. I currently have no idea why a property need a special mock but I guess I'll dig in the documentation to understand. – David Dahan Mar 09 '18 at 15:11
  • I think what happens is that the moment you apply the mock (without `PropertyMock`) it replaces the `_next_automatic_service_days` attribute with a magic mock which doesn't function as a descriptor. I guess it would need to be called to return its value (i.e. you would need to do `for day in self._next_automatic_service_days():`; note the `()`). The `PropertyMock` on the other hand allows to use the mocked attribute just like a property. I haven't tried that though. [The docs](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock) also provide some good information. – a_guest Mar 09 '18 at 16:03

0 Answers0