I have the following code in my testcase. Whenever I'm running the testcase, a new token is generated which is draining my quota.
So,instead of actual token I want to use some mock value which needs to be authenticated by the APIClient successfully. How do I mock this token authentication ?
Any help is much appreciated. Thanks
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTStatelessUserAuthentication',
],
from apps.common.helpers import get_auth0_access_token
class TestDatasetListTestCase(APITestCase):
def setUp(self):
access_token = get_auth0_access_token()
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {access_token}")
payload = {"label": "new_label"}
response = self.client.post(self.url, payload, format="multipart")
def generate_new_auth0_token()
options = {
"url": f"https://{auth0_domain}/oauth/token",
"headers": {"cache-control": "no-cache", "content-type": "application/json"},
"json": {"audience": audience, "grant_type": grant_type, "client_id": client_id, "client_secret": client_secret},
}
res = requests.post(**options)
return res.json() or Exception(res.text)
In unit tests, the standard procedure for external APIs is to have them mocked. There is no point in calling these APIs during tests because these are expected to work unless something changes on the other side (like changing APIs), but it is not expected in your case because you are using a standard API (with a fixed set of specifications by oAuth), unless the client server is down.
class TestDatasetListTestCase(APITestCase):
@mock.patch('apps.common.helpers.get_auth0_access_token')
def test_access_token(self, mock_access_token):
mock_access_token.return_value = SomeFactory().get_test_access_token() # just using Factory pattern here, it can be hard coded string
access_token = get_auth0_access_token()
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {access_token}")
payload = {"label": "new_label"}
response = self.client.post(self.url, payload, format="multipart")
If you still willing to to test APIClient, then I suggest setting up a mock oAuth server, like this opensource project Mock oAuth Server
. Then you can provide the test url the API calls (Or mock it). Lets say your url is defined in settings, you can try like this:
from django.test import override_settings
@override_settings(API_AUTH_URL='http://localhost:8989', CLIENT_SECRET='something', CLIENT_ID='else')
class TestDatasetListTestCase(APITestCase):
And update the helper function:
def generate_new_auth0_token()
options = {
"url": f"https://{settings.API_AUTH_URL}/oauth/token",
"headers": {"cache-control": "no-cache", "content-type": "application/json"},
"json": {"audience": audience, "grant_type": grant_type, "client_id": settings.CLIENT_ID, "client_secret": settings.CLIENT_SECRET},
}
More information can be found in the documentation regarding settings override.