2010-03-18 14 views
42

que tiene una forma como:Unidad de Prueba de un formulario de Django con un FileField

#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()) 

¿Cómo construir el file_dict pasar upload_file a la forma?

Respuesta

68

Hasta ahora he encontrado de esta manera que funciona

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

Dependiendo de lo que haga su código de carga, es posible que necesite establecer el atributo 'content_type' de upload_file, también –

+0

Donde content_type es una cadena como ''imagen/jpeg'' para un archivo de imagen jpg, por ejemplo. – Medeiros

+0

Obtengo 'TypeError: 'str' no admite la interfaz de buffer'. – Ariel

21

puede ser que esto no es del todo correcto, pero estoy crear archivo de imagen en prueba de la unidad utilizando 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

Pruebo el formulario por separado de la vista. En realidad, aún no he hecho la vista. –

+0

Ok, parece que SimpleUploadedFile es una solución bastante clara para probar – dragoon

+7

+1 por no tener que usar un archivo externo – Khelben

2

Aquí hay otro forma en que no requiere el uso de una imagen real.

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

Actualmente existe el siguiente pero: 'TypeError: string argument expected, got 'bytes''. Lo resolví usando 'BytesIO' en lugar de' StringIO', sin usar 'im_io.len' porque los objetos' BytesIO' no tienen atributo de longitud. – SalahAdDin

+0

@SalahAdDin Gracias por el aviso. Probé el código anterior en Python 2.7 y funciona bien. ¿Podría decirme qué versión de Python y Django está utilizando? Me gustaría corregir el código anterior para futuros lectores. Gracias. – xyres

+1

Estoy usando 'django 1.9' y' python 3.5'. – SalahAdDin

Cuestiones relacionadas