Django Rest: how to mock FileField and ImageField to_representation()
I have a model with 2 fields: image (ImageField) and media (FileField). They both use a custom GoogleCloudMediaStorage.
When writing my tests, I cannot access GCS, so I mocked the writing of the files by doing this:
from unittest.mock import patch
@patch('my_project.storage_backends.CustomGoogleCloudMediaStorage.save')
def test(self, mock_save):
mock_save.return_value = 'mocked_file.png'
# rest of the test
And it's working fine. The problem is now I have to test update and list views. When I do so, I have of course this error:
google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application.
After digging it a bit, I see that the error is triggered by the serializer to_representation()
. And more precisely in the FileField
:
def to_representation(self, value):
if not value:
return None
use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)
if use_url:
try:
url = value.url # !! THIS LINE CAUSE THE ISSUE
except AttributeError:
return None
request = self.context.get('request', None)
if request is not None:
return request.build_absolute_uri(url)
return url
So I tried to mock FileField.to_representation()
doing this:
@patch('django.db.models.FileField.to_representation')
def test_update(self, mock_representation):
mock_representation.return_value = 'mocked_training_file_url'
data = {
'title': 'Updated',
}
response = self.client.patch(. . .)
But I have this error:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/unittest/mock.py", line 1322, in patched
with self.decoration_helper(patched,
File "/usr/local/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.8/unittest/mock.py", line 1304, in decoration_helper
arg = exit_stack.enter_context(patching)
File "/usr/local/lib/python3.8/contextlib.py", line 425, in enter_context
result = _cm_type.__enter__(cm)
File "/usr/local/lib/python3.8/unittest/mock.py", line 1393, in __enter__
original, local = self.get_original()
File "/usr/local/lib/python3.8/unittest/mock.py", line 1366, in get_original
raise AttributeError(
AttributeError: <class 'django.db.models.fields.files.FileField'> does not have the attribute 'to_representation'
Any idea how I can mock FileField
and ImageField
to_representation()
? Am I doing this correctly