Проблема с тестированием сообщений в Django 5 CreateView

Я пишу юнит-тесты приложения для каталога электронных книг в Django 5. Страница создания книги использует встроенный CreateView. Код класса выглядит следующим образом:

class BookCreate(SuccessMessageMixin, PermissionRequiredMixin, CreateView):

    model = Book
    fields = ['title', 'author', 'genre', 'publisher', 'pages', 'cover', 'summary']

    template_name = 'books/add_book.html'
    permission_required = 'catalog.add_book'
    permission_denied_message = 'Not enough permissions to add a book'

    success_message = 'Book successfully added'
    success_url = reverse_lazy('add-book')

Работает это следующим образом: пользователь заполняет данные книги, нажимает кнопку submit, затем происходит перенаправление на ту же страницу, плюс на странице выводится сообщение, указанное в атрибуте success_message класса

Для тестирования я использую MessagesTestMixin, как описано в документации Django. Вот код юнит-теста:

class TestBookCreateView(MessagesTestMixin, TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.test_user = User.objects.create_user(
            email='john123@gmail.com',
            username='John',
            password='Fiesta123'
        )
        cls.add_book_permission = Permission.objects.get(codename='add_book')


    def setUp(self):
        login = self.client.login(username='Ivan', password='Fiesta123')
        self.test_user.user_permissions.set([self.add_book_permission])

    def test_if_view_success_message_attached(self):

        author = Author.objects.create(
            first_name='Charles',
            last_name='Dickens'
        )

        genre = Genre.objects.create(
            genre='Novel'
        )

        book_data = {
            'title': 'Great Expectations',
            'author': author,
            'genre': genre
        }

        response = self.client.post(reverse('add-book'), data=book_data, follow=True)
        self.assertMessages(response, 'Book successfully added')

Тест провален, в результатах вместо сообщения я вижу пустой список. Однако в приложении сообщение успешно передается в шаблон страницы, и я вижу его на странице после создания книги. Бэкенд хранилища сообщений в settings.py явно не задан, поэтому приложение использует storage.fallback.FallbackStorage, предоставляемый по умолчанию.

Так что же может быть проблемой в этом случае и вообще, каковы хорошие практики для тестирования сообщений в Django CBV?

Посмотрите на определение MessagesTestMixin.

class MessagesTestMixin:
    def assertMessages(self, response, expected_messages, *, ordered=True):
        request_messages = list(get_messages(response.wsgi_request))
        assertion = self.assertEqual if ordered else self.assertCountEqual
        assertion(request_messages, expected_messages)

Он просто сравнивает сообщения с помощью assertEqual (одинаковое содержимое, одинаковый порядок) или assertCountEqual (одинаковое содержимое, но в любом порядке) с тем, что вы передадите. Сообщения хранятся в виде списка экземпляров django.contrib.messages.storage.base.Message, поэтому, чтобы утверждение было истинным, вы должны построить эквивалентный список.

from django.contrib import messages
from django.contrib.messages.test import MessagesTestMixin

class TestBookCreateView(MessagesTestMixin, TestCase):
    def test_if_view_success_message_attached(self):
        # ...
        self.assertMessages(response, [
            messages.Message(messages.SUCCESS, 'Book successfully added'),
        ])

(Я предположил, что ваше сообщение было сообщением об успехе. возможные константы: DEBUG, INFO, SUCCESS, WARNING и ERROR.)

Вернуться на верх