Reputation: 14071
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
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
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
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