2012-03-03 13 views
12

Ho la seguente logica a mio avviso:Django - come unità di testare una richiesta POST utilizzando request.FILES

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

Dove UploadFileForm equivale a:

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

sto cercando di scrivere all'unità prova per questa vista. Guardando in docs Django, il modo suggerito è questo:

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 

Il mio obiettivo è quello di ottenere uploadform.is_valid() per valutare True, così posso testare il codice che segue la validazione dei form. Quando eseguo il test sopra, uploadform.is_valid() restituisce False. C'è qualcosa che mi manca? Il codice nel mio test aggiunge il file a request.FILES, o sta facendo qualcos'altro?

+0

Se non sei sicuro di ciò che è in 'request.FILES', la cosa più rapida da fare è aggiungere aggiungi una dichiarazione di stampa nella tua vista per vedere cosa sta succedendo. – Alasdair

+0

hmm L'ho provato ma l'argomento FILES non è stato incluso nella stampa. C'è un'impostazione per abilitarlo? – vasek1

risposta

15

Nei documenti, il campo del file si chiama attachment, ma nel tuo si chiama file.

Non è necessario name nei dati del tuo annuncio - che si riferisce a un altro campo chiamato name, non al nome del file che stai caricando.

provare quanto segue:

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

forse mi manca qualcosa qui, ma suona come un lavoro per una buona biblioteca finto. Personalmente mi piace molto lo Mock. Ma, cado nel campo che crede che i tuoi test unitari dovrebbero essere liberi da tutte le dipendenze esterne (come avere un file chiamato "file.csv" in una certa posizione, ecc.)

+0

libreria ordinata. Non lo sapevo ma sicuramente daremo un'occhiata più da vicino. Grazie! – vasek1

+2

È stato annunciato che Mock verrà aggiunto alla libreria Std di Python, probabilmente è una buona cosa da imparare. Ecco un video di Michael Foord (autore originale di Mock) negli ultimi anni PyCon. http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-testing-with-mock-4899484 e anche un video da un discorso di PyCon di quest'anno che ho pensato fosse davvero buono. http://pyvideo.org/video/699/testing-and-django - Consiglio di controllarli entrambi. –

30

Il modo in cui la suite di test di django fa è:

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

in questo modo non è necessario creare un file temporaneo e scrivere su di esso, e non è necessario prendere in giro un file (non è così facile come sembra).

+0

Grazie mille. Stavo cercando di usare Factory richiesta per prendere in giro il file in arrivo. Ho appena inserito il codice in sostituzione dei valori e lavorato al primo tentativo. – hectorcanto

+1

Grazie, mi hai salvato dal prendere in giro un file! Aggiornamento per Python3 django 1.10 Ho dovuto inserire 'b' prima del contenuto del file, come questo' f = SimpleUploadedFile ("file.txt", b "file_content") 'a causa di TypeError –

Problemi correlati