vasek1
vasek1

Reputation: 14071

django - how to unit test a post request using request.FILES

I have the following logic in my view:

def view_function(request):
    if request.method == 'POST':
        uploadform = UploadFileForm(request.POST, request.FILES)
        if uploadform.is_valid():
            #do stuff

Where UploadFileForm equals to:

class UploadFileForm(forms.Form):
    file = forms.FileField()

I am trying to write unit tests for this view. Looking in Django docs, the suggested way is this:

class test_stuffTest(TestCase):
    def setUp(self):
        self.client = django.test.client.Client()
    ...
    def test_stuff(self):
        myfile = open('....\file.csv','r')
        response = self.client.post('/', {'name':'file.csv','attachment':myfile})
        #check response

My goal is to get uploadform.is_valid() to evaluate to True, so I can test the code which follows the form validation. When I run the test above, uploadform.is_valid() evaluates to False. Is there anything I am missing? Is the code in my test adding the file to request.FILES, or is it doing something else?

Upvotes: 21

Views: 20633

Answers (3)

radu.ciorba
radu.ciorba

Reputation: 1054

The way django's testsuite does it is:

from django.core.files.uploadedfile import SimpleUploadedFile
f = SimpleUploadedFile("file.txt", b"file_content")

This way you don't need to create a temp file and write to it, and you don't need to mock a file (not as easy as it sounds).

Upvotes: 45

Alasdair
Alasdair

Reputation: 308769

In the docs, the file field is called attachment, but in yours, it's called file.

You don't need name in your post data either -- that refers to another field called name, not the name of the file that you are uploading.

Try the following:

def test_stuff(self): 
    myfile = open('....\file.csv','r') 
    response = self.client.post('/', {'file':myfile})

Upvotes: 23

David S
David S

Reputation: 13841

Maybe I'm missing something here, but sounds like a job for a good mock library. I personally really like Mock. But, I fall into the camp that believes that your unit tests should be free of all external dependencies (like having to have a file named "file.csv" in a certain location, etc.)

Upvotes: 3

Related Questions