Задать вопрос
@YuriyCherniy

Как покрыть тестом clean метод формы Django?

Есть вот такая простая форма Django:
from django.forms import ModelForm, ValidationError
from django.core.files.images import get_image_dimensions

from .models import Item


class ItemModelForm(ModelForm):
    class Meta:
        model = Item
        fields = ['title', 'description', 'image', 'price']

    def clean_image(self):
        '''
        Only 1:1 format is allowed
        '''
        image = self.cleaned_data.get('image')
        width, height = get_image_dimensions(image)
        if width == height:
            return image
        raise ValidationError('Формат изображения должен быть 1:1!')

Не получается подсунуть в форму тестовый файл изображения. Пытаюсь тестить как-то так:
from io import BytesIO

from PIL import Image

from django.test import SimpleTestCase
from django.core.files.uploadedfile import InMemoryUploadedFile

from showcase.forms import ItemModelForm


def create_test_image():
    file = BytesIO()
    image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
    image.save(file, 'png')
    file.name = 'test.png'
    file.seek(0)
    return file


class TestForms(SimpleTestCase):
    def test_item_model_form_valid_data(self):
        form = ItemModelForm(
            data={
                'title': 'test_title`',
                'description': 'test_description' * 10,
                'price': 500,
                'image': InMemoryUploadedFile(
                    file=create_test_image(),
                    field_name='image',
                    name='test.png',
                    content_type='image/png',
                    size=45,
                    charset='utf-8'
                )
            }
        )
        self.assertTrue(form.is_valid())

На это тест form.errors ругается, что поле image обязательное. Подскажите куда копать? Или может есть какой-нибудь другой подход к решению проблемы тестирования clean метода?
  • Вопрос задан
  • 272 просмотра
Подписаться 2 Средний Комментировать
Решения вопроса 1
@YuriyCherniy Автор вопроса
В общем сам себе ответил, рабочий тест выглядит так:
def test_item_model_form_valid_data(self):
        data = {
                'title': 'test_title`',
                'description': 'test_description' * 10,
                'price': 500
            }

        file_data = {
            'image': InMemoryUploadedFile(
                    file=create_test_image(),
                    field_name='image',
                    name='test.png',
                    content_type='image/png',
                    size=45,
                    charset='utf-8'
            )
        }

        form = ItemModelForm(data=data, files=files_data)
        self.assertTrue(form.is_valid())

Входные данные data и файл file_data необходимо передавать в форму отдельно, проблема была в этом. Думается мне, что это не лучший способ тестировать форму, но гуру к сожалению не подключились. Надо будет ещё поиграться с mock, истина должна быть где-то там.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы