Reputation: 191
In the following class the property wheels
has a cached value.
import time
class Car:
@property
def wheels(self):
if not hasattr(self, '_wheels'):
self._count_wheels()
return self._wheels
def _count_wheels(self):
time.sleep(10) # simulate a long calculation
self._wheels = 4
if __name__ == "__main__":
c = Car()
print(c.wheels) # calls _count_wheels() once
print(c.wheels) # no calls to _count_wheels()
I want to test that the first call to c.wheels
calls once the method _count_wheels()
; while the second call to c.wheels
doesn't call the method _count_wheels()
I'd like to use unittest.mock
Upvotes: 3
Views: 1215
Reputation: 17485
One simple solution is to mock the object yourself:
if __name__ == "__main__":
count = 0
to_mock = Car._count_wheels
def mocked(self):
global count
count +=1
if count>1:
raise ValueError("Called twice")
to_mock(self)
Car._count_wheels = mocked
c = Car()
print(c.wheels) # calls _count_wheels() once
try:
print(c.wheels) # no calls to _count_wheels()
except ValueError as e:
print e
You can try it with this modified Car
class:
class Car:
@property
def wheels(self):
#if not hasattr(self, '_wheels'):
self._count_wheels()
return self._wheels
def _count_wheels(self):
#time.sleep(10) # simulate a long calculation
self._wheels = 4
And you will see it raises the exception. Since python is so dynamic this approach is always valid and sometimes is very useful, but of course you can use a third party tool as well ;)
Upvotes: 1