I'm trying to test a self written FormField AudioFileFormField, which checks if a file is an audiofile before storing it. For that i have overwritten the to_python method. Trying to test this FormField i ran into some difficulties.
This is my TestCase so far:
from django import forms
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
class TestAudioFileFormField(TestCase):
""" test the formfield to use for AudioFile Uploads """
class TestForm(forms.Form):
audiofilefield = AudioFileFormField()
def setUp(self):
self.AUDIOFILE_TEST_ROOT = os.path.dirname(__file__) + '/data/'
self.files = audiofile_files
def test_to_python(self):
""" assign some files to a form and validate the form """
f = file(self.AUDIOFILE_TEST_ROOT + self.files[0])
file_data = {'audiofilefield':SimpleUploadedFile( self.files[0],f.read() )}
data = {}
form = self.TestForm(data,f)
form.is_valid()
The line form.is_valid() raises an AttributeError: 'file' object has no attribute 'get'
When i insert a debug trace right before form.is_valid(), this is what i get in that interactive session:
ipdb> form.is_valid()
AttributeError: 'file' object has no attribute 'get'
ipdb> suf = file_data['audiofilefield']
ipdb> suf
<SimpleUploadedFile: invalid_format.mp3 (text/plain)>
ipdb> dir(suf)
[lots of info here]
ipdb> form.is_valid()
True
What exactly did i change in the interactive session, so that the form validation is working? What would be the correct way to pass the file to SimpleUploadedFile to avoid the AttributeError?
Ok, a fresh look can be worth a lot. This is my new test_to_python test, this time it works:
def test_to_python(self):
f = file(self.AUDIOFILE_TEST_ROOT + self.files[0])
file_data = {'audiofilefield':SimpleUploadedFile(self.files[0],f.read())}
data = {}
form = self.TestForm(data,file_data)
self.assertTrue( form.is_valid() )
Alternative solution (because this question is the top Google result for "Django test simulate upload"): Django's builtin test client accepts open file objects as POST data:
# the form
class TestForm(forms.Form):
audiofilefield = AudioFileFormField()
# the view
def upload_view(request):
form = TestForm(data=request.POST or None, files=request.FILES or None)
if request.method == 'POST':
if form.is_valid():
return HttpResponse('success')
else:
return HttpResponse('fail')
# the test function
class UploadTest(TestCase):
def test_upload(self):
c = Client() # django.test.client.Client
formdata = {}
with open('/my/audiofile.mp3', 'rb') as f:
formdata['audiofilefield'] = f
response = c.post('/my-test-view/', formdata)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With