When testing file uploads, you should pass the stream object into the request, not the data.
This was pointed out in the comments by @arocks
Pass { ‘image’: file} instead
But that didn’t full explain why it was needed (and also didn’t match the question). For this specific question, you should be doing
from PIL import Image
class TestFileUpload(APITestCase):
def test_file_is_accepted(self):
self.client.force_authenticate(self.user)
image = Image.new('RGB', (100, 100))
tmp_file = tempfile.NamedTemporaryFile(suffix='.jpg')
image.save(tmp_file)
tmp_file.seek(0)
response = self.client.post('my_url', {'image': tmp_file}, format="multipart")
self.assertEqual(status.HTTP_201_CREATED, response.status_code)
This will match a standard Django request, where the file is passed in as a stream object, and Django REST Framework handles it. When you just pass in the file data, Django and Django REST Framework interpret it as a string, which causes issues because it is expecting a stream.
And for those coming here looking to another common error, why file uploads just won’t work but normal form data will: make sure to set format="multipart"
when creating the request.
This also gives a similar issue, and was pointed out by @RobinElvin in the comments
It was because I was missing format=”multipart”