2012-03-03 28 views
12

我已經在我看來,以下邏輯如何進行單元測試的POST請求:Django的 - 使用request.FILES

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

凡UploadFileForm等於:

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

我想寫單元測試這個觀點。展望Django文檔,建議的方式是這樣的:

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 

我的目標是讓uploadform.is_valid(),以評估爲True,所以我可以測試下面的表單驗證代碼。當我運行上面的測試時,uploadform.is_valid()的計算結果爲False。有什麼我失蹤?我的測試中的代碼是將文件添加到request.FILES中,還是在執行其他操作?

+0

如果您不確定'request.FILES'中的內容,最快的方法是在視圖中添加一條打印語句以查看發生了什麼。 – Alasdair 2012-03-03 20:32:26

+0

嗯我試過,但FILES參數不包含在打印輸出中。有沒有啓用它的設置? – vasek1 2012-03-03 23:35:13

回答

15

在文檔中,文件字段被稱爲attachment,但在您的文件中,它被稱爲file

您的發佈數據中不需要name - 這是指稱爲name的另一個字段,而不是您要上傳的文件的名稱。

嘗試以下操作:

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

也許我失去了一些東西,但聽起來像一個很好的模擬圖書館工作。我個人非常喜歡Mock。但是,我陷入了認爲你的單元測試應該沒有任何外部依賴的陣營(比如必須在某個位置上有一個名爲「file.csv」的文件等)。

+0

整齊的圖書館。不知道,但一定會仔細看看。謝謝! – vasek1 2012-03-03 23:49:49

+2

已經宣佈將Mock添加到Python的Std Library中,這可能是一件好事。這是Michael Foord(Mock的原創作者)在去年PyCon的一段視頻。 http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-testing-with-mock-4899484以及來自今年PyCon講話的視頻,我認爲這很好。 http://pyvideo.org/video/699/testing-and-django - 我建議兩個都檢查一下。 – 2012-05-18 21:58:31

30

django的測試套件它是:

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

這樣你就不需要創建一個臨時文件,並寫入它,你不必嘲笑文件(並不像聽起來那麼容易)。

+0

非常感謝。 我正在嘗試使用請求工廠來模擬傳入的文件。只需將您的代碼替換值並在第一次嘗試中工作。 – hectorcanto 2016-04-11 15:55:02

+1

謝謝,你救了我嘲笑一個文件! Python3的更新django 1.10我必須在文件內容之前放置'b',就像'f = SimpleUploadedFile(「file.txt」,b「file_content」)'由於TypeError – 2016-10-05 17:54:46

相關問題