Skip to content

Instantly share code, notes, and snippets.

@nghiaht
Created March 21, 2019 09:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nghiaht/682c2d8d40272c52dbf7adf214f1c0f1 to your computer and use it in GitHub Desktop.
Save nghiaht/682c2d8d40272c52dbf7adf214f1c0f1 to your computer and use it in GitHub Desktop.
Testing Django Rest Framework with multipart/form-data request
from django.test import TestCase
from rest_framework.test import APIClient
class FileUploadTestCase(TestCase):
def test_upload(self):
client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
# or self.client (Django https://docs.djangoproject.com/en/dev/topics/testing/advanced/)
response = client.post(reverse('upload-file'), {
"image": open("tests/test.png", "rb"),
"name": "test"
})
self.assertEqual(200, response.status_code)
@cocomatias
Copy link

Hi!, this doesn't work!

@nghiaht
Copy link
Author

nghiaht commented May 19, 2021

Hi!, this doesn't work!

It depends on how you declare the serializer (serializers.py). Could you check again?

@EtudiantInformatique78
Copy link

EtudiantInformatique78 commented Jul 6, 2021

I have fixed the problem with that:

import io
from django.test import TestCase

class test(TestCase):
    def test_upload_file(self):
        with open('/path/to/file.txt', 'rb') as fp :
            fio  = io.FileIO(fp.fileno())
            fio.name = 'file.txt'
            r = self.client.post('/url/', {'filename': fio, 'extraparameter': 5})
        self.assertEqual(r.headers['Content-Type'], 'application/json')

url.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'/url/$', views.serverside_method, name="serverside_method")
]

Example on the server-side (view.py)

def serverside_method(request):    
    if 'filename' in request.FILES:
        file_request = request.FILES['filename']
        file_size = file_request.size
        file_request_name = file_request.name
        return JsonResponse({'Success': True})
    else:
        return JsonResponse({'Success': False})

@AllStar6581
Copy link

AllStar6581 commented Dec 17, 2021


from rest_framework.test import APITestCase
from django.test.client import MULTIPART_CONTENT, encode_multipart, BOUNDARY
from django.core.files.base import ContentFile  

class FileUploadTestCase(APITestCase):  
    def test_upload(self):
        document = ContentFile(b"foo", "test.png")
        url = reverse("upload-file")
        response = self.client.post(
            path=url,
            data=encode_multipart(data = dict(image=document, name="test"), boundary=BOUNDARY),
            content_type=MULTIPART_CONTENT,
            HTTP_AUTHORIZATION=f"Token {self.token.key}"
        )

        self.assertEqual(200, response.status_code)
        

@webfactorycuba
Copy link

@AllStar6581 's response works for me, thanks, more than a year but still effective :)

@MichelML
Copy link

thanks @AllStar6581 , this is the cleanest of all

@Beenhakker
Copy link

Thanks @AllStar6581 lifesaver.

@bdmbdsm
Copy link

bdmbdsm commented May 12, 2023

Thanks, @AllStar6581
I was not using encode_multipart and the view received no data.

@Hackerbot1488
Copy link

@AllStar6581 Thank you! I was searching for working solution for 2 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment