I have a custom throttle class like: (print statements are for debugging :)) in api.throttle.py
print("befor CustomThrottle class")
class CustomThrottle(BaseThrottle):
def __init__(self):
super().__init__()
print("initializing CustomThrottle", self)
self._wait = 0
def allow_request(self, request, view):
print("CustomThrottle.allow_request")
if request.method in SAFE_METHODS:
return True
# some checking here
if wait > 0:
self._wait = wait
return False
return True
def wait(self):
return self._wait
my api.views.py
is like:
from api.throttle import CustomThrottle
print("views module")
class SomeView(APIView):
print("in view")
throttle_classes = [CustomThrottle]
def post(self, request, should_exist):
# some processing
return Response({"message": "Done."})
and my tests is api/tests/test_views.py
:
@patch.object(api.views.CustomThrottle, "allow_request")
def test_can_get_confirmation_code_for_registered_user(self, throttle):
throttle.return_value = True
response = self.client.post(path, data=data)
self.assertEqual(
response.status_code,
status.HTTP_200_OK,
"Should be successful",
)
@patch("api.views.CustomThrottle")
def test_learn(self, throttle):
throttle.return_value.allow_request.return_value = True
response = self.client.post(path, data=data)
self.assertEqual(
response.status_code,
status.HTTP_200_OK,
"Should be successful",
)
the first test passes correctly but still the CustomThrottle
class is instantiated but the allow_request
method is mocked; the second test shows that neither CustomThrottle
class is mocked nor the allow_request
method and it fails with status 429
(CustomThrottle
has a throttle rate of 2 minutes).
After spending some time and testing different scenarios (Putting debug like print statements here and there :) ) I finally found out why it's not working, But it may not be as correct as I think so any better answer is welcome.
I defined list of throttle classes like throttle_classes = [CustomThrottle]
so when server starts it's imported and evaluated so there's a reference to the actual and unmocked version of CustomThrottle
in my SomeView
class and when processing the responses it will use that for instantiation and so my test fails, but when I patch it like patch.object(CustomThrottle, "allow_request")
when view actually needs to check throttles it will call something like CustomThrottle().allow_request(...)
(pay attention to parentheses for object creation); the object has not a method like allow_request
in itself so it searches that in it's class and use the mocked version correctly.
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