2010-03-18 9 views
42

Ich habe eine Form wie:Einheit ein Django-Formulars mit einem Filefield Testen

#forms.py 
from django import forms 

class MyForm(forms.Form): 
    title = forms.CharField() 
    file = forms.FileField() 


#tests.py 
from django.test import TestCase 
from forms import MyForm 

class FormTestCase(TestCase) 
    def test_form(self): 
     upload_file = open('path/to/file', 'r') 
     post_dict = {'title': 'Test Title'} 
     file_dict = {} #?????? 
     form = MyForm(post_dict, file_dict) 
     self.assertTrue(form.is_valid()) 

Wie kann ich den file_dict konstruierenUPLOAD_FILE das Formular übergeben?

Antwort

68

Bisher habe ich auf diese Weise gefunden haben, die

from django.core.files.uploadedfile import SimpleUploadedFile 
... 
def test_form(self): 
     upload_file = open('path/to/file', 'rb') 
     post_dict = {'title': 'Test Title'} 
     file_dict = {'file': SimpleUploadedFile(upload_file.name, upload_file.read())} 
     form = MyForm(post_dict, file_dict) 
     self.assertTrue(form.is_valid()) 
+1

Je nachdem, was Ihr Upload-Code tut, müssen Sie möglicherweise die 'content_type' Attribut von upload_file, auch –

+0

Where content_type ist eine Zeichenkette wie "image/jpeg" für eine JPG-Bilddatei. – Medeiros

+0

Ich bekomme 'TypeError: 'str' unterstützt die Pufferschnittstelle nicht. – Ariel

21

Kann sein, das ist nicht ganz richtig, aber ich bin zu schaffen Bilddatei in Unit-Test unter Verwendung von StringIO:

imgfile = StringIO('GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00' 
        '\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;') 
imgfile.name = 'test_img_file.gif' 

response = self.client.post(url, {'file': imgfile}) 
+2

Ich versuche, das Formular getrennt von der Ansicht zu testen. Eigentlich habe ich noch nicht einmal die Aussicht gemacht. –

+0

Ok, scheint SimpleUploadedFile eine ziemlich klare Lösung zum Testen – dragoon

+7

+1 für die Notwendigkeit, eine externe Datei verwenden – Khelben

2

Hier arbeitet ein anderer So benötigen Sie kein tatsächliches Bild.

from PIL import Image 
from StringIO import StringIO # Python 3: from io import StringIO 
from django.core.files.uploadedfile import InMemoryUploadedFile 

... 

def test_form(self): 
    im = Image.new(mode='RGB', size=(200, 200)) # create a new image using PIL 
    im_io = StringIO() # a StringIO object for saving image 
    im.save(im_io, 'JPEG') # save the image to im_io 
    im_io.seek(0) # seek to the beginning 

    image = InMemoryUploadedFile(
     im_io, None, 'random-name.jpg', 'image/jpeg', im_io.len, None 
    ) 

    post_dict = {'title': 'Test Title'} 
    file_dict = {'picture': image} 

    form = MyForm(data=post_dict, files=file_dict) 
+3

Momentan existiert das nächste aber: 'TypeError: string argument expected, get 'bytes''. Ich löste es mit 'BytesIO' anstelle von' StringIO', ohne 'im_io.len' zu verwenden, da ein' BytesIO' Objekt kein Längenattribut hat. – SalahAdDin

+0

@SalahAdDin Danke für die Köpfe hoch. Ich habe den obigen Code in Python 2.7 getestet und es funktioniert gut. Kannst du mir bitte sagen, welche Version von Python und Django du verwendest? Ich möchte den obigen Code für zukünftige Leser korrigieren. Vielen Dank. – xyres

+1

Ich benutze 'Django 1.9' und' Python 3.5'. – SalahAdDin

Verwandte Themen