2016-11-16 72 views
2

我想單元測試我的文件上傳REST API。我在網上找到一些代碼用枕頭生成圖像,但它不能被序列化。Django Rest Framework - 單元測試圖像文件上傳

這是我的生成圖像代碼:

image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0)) 
file = BytesIO(image.tobytes()) 
file.name = 'test.png' 
file.seek(0) 

然後我嘗試上傳這個圖片,並祝:

return self.client.post("/api/images/", data=json.dumps({ 
    "image": file, 
    "item": 1 
}), content_type="application/json", format='multipart') 

而且我得到以下錯誤:

<ContentFile: Raw content> is not JSON serializable 

如何轉換Pillow圖像以使其可序列化?

+0

您是否嘗試省略'json.dumps'調用?在我的django項目中,我只是使用測試客戶端將數據作爲字典發佈。 – Brobin

回答

2

我不會建議提交在這種情況下您的數據,JSON,因爲這個問題複雜化。只需使用要提交的參數和文件進行POST請求即可。 Django REST Framework可以很好地處理它,無需將其作爲JSON序列化。

我寫了一個測試文件上載到的API端點而回看起來像這樣:

def test_post_photo(self): 
    """ 
    Test trying to add a photo 
    """ 
    # Create an album 
    album = AlbumFactory(owner=self.user) 

    # Log user in 
    self.client.login(username=self.user.username, password='password') 

    # Create image 
    image = Image.new('RGB', (100, 100)) 
    tmp_file = tempfile.NamedTemporaryFile(suffix='.jpg') 
    image.save(tmp_file) 

    # Send data 
    with open(tmp_file.name, 'rb') as data: 
     response = self.client.post(reverse('photo-list'), {'album': 'http://testserver/api/albums/' + album.pk, 'image': data}, format='multipart') 
     self.assertEqual(response.status_code, status.HTTP_201_CREATED) 

在這種情況下,我使用的tempfile模塊,用於存儲圖像使用枕頭生成。示例中使用的with語法允許您比較容易地傳遞請求正文中的文件內容。

在此基礎上,這樣的事情應該爲您的使用情況下工作:

image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0)) 
file = tempfile.NamedTemporaryFile(suffix='.png') 
image.save(file) 

with open(file.name, 'rb') as data: 
    return self.client.post("/api/images/", {"image": data, "item": 1}, format='multipart') 

順便說一句,這取決於你使用的情況下,可以更方便地接受圖像數據作爲基64編碼字符串。

0

您將文件轉換爲不是JSON序列化的字節。

不知道你的API預期會收到什麼,我不得不猜測你必須將file作爲字符串編碼:"image": file.decode('utf-8')

雖然有許多單元測試圖像上傳您的一般性問題多解REST API