Джанго - как написать тест для DRF ImageField - PullRequest
0 голосов
/ 27 мая 2019

У меня есть следующий сериализатор:

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: Объект типа 'BufferedRandom' не является сериализуемым JSON

В чем моя ошибка?Как я могу написать тест для поля изображения?

Ответы [ 2 ]

0 голосов
/ 27 мая 2019

Я предлагаю использовать SimpleUploadedFile класс из django и создавать и создавать изображения с использованием пакета 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)
0 голосов
/ 27 мая 2019

Обычно, когда вы загружаете файл, вы используете формат запроса 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)

Что это делает:

  1. Создание изображения в памяти с помощью PIL.Image
  2. Создать NamedTeoraryFile для хранения данных изображения
  3. Возьмите NamedTeoraryFile и прочитайте в InMemoryUploadedFile
  4. Передать этот файл InMemoryUploadedFile в сериализатор
...