Django Rest框架-单元测试镜像文件上传



我正在尝试单元测试我的文件上传REST API。我在网上找到了一些用Pillow生成图像的代码,但它不能序列化。

这是我生成图像的代码:
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

我如何转换枕头图像,使其可序列化?

我不建议在这种情况下以JSON形式提交数据,因为这会使问题复杂化。只需用您想要提交的参数和文件创建一个POST请求。Django REST框架可以很好地处理它,而不需要将其序列化为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模块来存储使用Pillow生成的图像。示例中使用的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')

顺便说一下,根据您的使用情况,接受图像数据作为base 64编码字符串可能更方便。

您将文件转换为字节,这是不可JSON序列化的。

不知道您的API期望接收什么,我将不得不猜测您必须将file编码为字符串:"image": file.decode('utf-8')

虽然单元测试的一般问题有许多解决方案,但图像上传到REST API

最新更新