Django - 如何为 DRF ImageField 编写测试
Django - how to write test for DRF ImageField
我有以下序列化程序:
from rest_framework.serializers import Serializer, ImageField
class MySerializer(Serializer):
avatar = ImageField()
如何为它编写单元测试?
我使用了 Django TestCase,但它引发了一个错误。
from django.test import TestCase
class MySerializerTest(TestCase):
def setUp(self):
self.data = {}
...
def test_image(self):
import tempfile
self.data['avatar'] = tempfile.NamedTemporaryFile(suffix=".jpg").file
r_data = json.dumps(self.data)
j_data = json.loads(r_data)
serializer = MySerializer(data=j_data)
if not serializer.is_valid():
import pprint
pprint.pprint(serializer.errors)
self.assertEqual(serializer.is_valid(), True)
但它引发了以下错误:
TypeError: Object of type 'BufferedRandom' is not JSON serializable
我的错误是什么?如何编写图像字段测试?
通常当您上传文件时,您会使用 multipart
请求格式,视图会将图像转换为 InMemoryUploadedFile
对象,然后将其传递到您的序列化程序中
因此,为了修复您的测试,我建议您尝试:
from PIL import Image
from tempfile import NamedTemporaryFile
from django.conf.files.uploadedfile import InMemoryUploadedFile
...
def test_image(self):
image = Image.new("RGB", (100, 100))
with NamedTemporaryFile(suffix=".png", mode="w+b") as tmp_file:
image.save(tmp_file, format="png")
tmp_file.seek(0)
byio = BytesIO(temp_file.read())
inm_file = InMemoryUploadedFile(
file=byio,
field_name="avatar",
name="testImage.png",
content_type="image/png",
size=byio.getbuffer().nbytes,
charset=None,
)
self.data['avatar'] = inm_file
serializer = MySerializer(data=self.data)
if not serializer.is_valid():
import pprint
pprint.pprint(serializer.errors)
self.assertEqual(serializer.is_valid(), True)
这是做什么的:
- 使用 PIL.Image
在内存中创建图像
- 创建一个 NamedTemporaryFile 来存储图像数据
- 获取 NamedTemporaryFile 并读入 InMemoryUploadedFile
- 将此 InMemoryUploadedFile 传递到序列化程序
我建议使用 django 中的 SimpleUploadedFile
class 并使用 Pillow 包创建图像。请参阅下面的示例。
from PIL import Image
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.utils.six import BytesIO
class MySerializerTest(TestCase):
...
def test_image(self):
image = BytesIO()
Image.new('RGB', (100, 100)).save(image, 'JPEG')
image.seek(0)
self.data['avatar'] = SimpleUploadedFile('image.jpg', image.getvalue())
serializer = MySerializer(data=self.data)
self.assertEqual(serializer.is_valid(), True)
我有以下序列化程序:
from rest_framework.serializers import Serializer, ImageField
class MySerializer(Serializer):
avatar = ImageField()
如何为它编写单元测试? 我使用了 Django TestCase,但它引发了一个错误。
from django.test import TestCase
class MySerializerTest(TestCase):
def setUp(self):
self.data = {}
...
def test_image(self):
import tempfile
self.data['avatar'] = tempfile.NamedTemporaryFile(suffix=".jpg").file
r_data = json.dumps(self.data)
j_data = json.loads(r_data)
serializer = MySerializer(data=j_data)
if not serializer.is_valid():
import pprint
pprint.pprint(serializer.errors)
self.assertEqual(serializer.is_valid(), True)
但它引发了以下错误:
TypeError: Object of type 'BufferedRandom' is not JSON serializable
我的错误是什么?如何编写图像字段测试?
通常当您上传文件时,您会使用 multipart
请求格式,视图会将图像转换为 InMemoryUploadedFile
对象,然后将其传递到您的序列化程序中
因此,为了修复您的测试,我建议您尝试:
from PIL import Image
from tempfile import NamedTemporaryFile
from django.conf.files.uploadedfile import InMemoryUploadedFile
...
def test_image(self):
image = Image.new("RGB", (100, 100))
with NamedTemporaryFile(suffix=".png", mode="w+b") as tmp_file:
image.save(tmp_file, format="png")
tmp_file.seek(0)
byio = BytesIO(temp_file.read())
inm_file = InMemoryUploadedFile(
file=byio,
field_name="avatar",
name="testImage.png",
content_type="image/png",
size=byio.getbuffer().nbytes,
charset=None,
)
self.data['avatar'] = inm_file
serializer = MySerializer(data=self.data)
if not serializer.is_valid():
import pprint
pprint.pprint(serializer.errors)
self.assertEqual(serializer.is_valid(), True)
这是做什么的:
- 使用 PIL.Image 在内存中创建图像
- 创建一个 NamedTemporaryFile 来存储图像数据
- 获取 NamedTemporaryFile 并读入 InMemoryUploadedFile
- 将此 InMemoryUploadedFile 传递到序列化程序
我建议使用 django 中的 SimpleUploadedFile
class 并使用 Pillow 包创建图像。请参阅下面的示例。
from PIL import Image
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.utils.six import BytesIO
class MySerializerTest(TestCase):
...
def test_image(self):
image = BytesIO()
Image.new('RGB', (100, 100)).save(image, 'JPEG')
image.seek(0)
self.data['avatar'] = SimpleUploadedFile('image.jpg', image.getvalue())
serializer = MySerializer(data=self.data)
self.assertEqual(serializer.is_valid(), True)