Consider that I have a simple APIView as below,
from rest_framework.views import APIView
from rest_framework.response import Response
def my_custom_decorator(func):
def wrap(view, request):
if request.method.lower():
raise ValueError("Just for testing")
return func(view, request)
return wrap
class SomeAPIView(APIView):
@my_custom_decorator
def post(self, request):
return Response({"message": "Success"})
Note that the view function post(...)
is wrapped by the decorator @my_custom_decorator
.
Noe, I want to write the test for this API and I tried like this
from rest_framework.test import APITestCase
from django.urls import reverse
from unittest.mock import patch
class TestSomeAPIView(APITestCase):
@patch("sample.views.my_custom_decorator")
def test_decorator(self, mock_my_custom_decorator):
url = reverse("some-api-view")
response = self.client.post(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), {"message": "Success"})
This didn't mock the @my_custom_decorator
properly and thus gave me an exception.
Question: How can I mock the @my_custom_decorator
to retrieve a successful response?
Notes
- I have seen this SO post, Can I patch a Python decorator before it wraps a function?, I feel that post lacks some examples,
Update - 1
This answer will work only if the test module gets initialized before the initialization of the view module. AFAIK, this kind of loading isn't configurable in Django.