2016-11-16 99 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