Как я могу провести модульное тестирование сообщений django? - PullRequest
66 голосов
/ 24 мая 2010

В моем приложении django я пытаюсь написать модульный тест, который выполняет действие, а затем проверяет сообщения в ответе.

Насколько я могу судить, хорошего способа сделать это не существует.

Я использую метод хранения CookieStorage, и я хотел бы сделать что-то похожее на следующее:

    response = self.client.post('/do-something/', follow=True)
    self.assertEquals(response.context['messages'][0], "fail.")

Проблема в том, что все, что я получаю, это

print response.context['messages']
<django.contrib.messages.storage.cookie.CookieStorage object at 0x3c55250>

Как я могу превратить это во что-то полезное, или я все делаю неправильно?

Спасибо, Daniel

Ответы [ 5 ]

60 голосов
/ 16 февраля 2013

Я нашел очень простой подход:

response = self.client.post('/foo/')
messages = list(response.context['messages'])
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), 'my message')

Если вам нужно проверить сообщения в ответе без контекста, вы можете использовать следующее:

from django.contrib.messages import get_messages
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), 'my message')

ОткатХранилище не поддерживает индексирование, однако оно является итеративным.

17 голосов
/ 08 февраля 2011

Это работает для меня (отображает все сообщения):

print [m.message for m in list(response.context['messages'])]

Также вот несколько утилитарных методов, которые у меня есть в тестовом классе, унаследованном от TestCase Django.Если вы предпочитаете, чтобы они были функциями, удалите аргументы self и замените self.fail() на raise.

def assert_message_count(self, response, expect_num):
    """
    Asserts that exactly the given number of messages have been sent.
    """

    actual_num = len(response.context['messages'])
    if actual_num != expect_num:
        self.fail('Message count was %d, expected %d' %
            (actual_num, expect_num))

def assert_message_contains(self, response, text, level=None):
    """
    Asserts that there is exactly one message containing the given text.
    """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) == 1:
        msg = matches[0]
        if level is not None and msg.level != level:
            self.fail('There was one matching message but with different'
                'level: %s != %s' % (msg.level, level))

        return

    elif len(matches) == 0:
        messages_str = ", ".join('"%s"' % m for m in messages)
        self.fail('No message contained text "%s", messages were: %s' %
            (text, messages_str))
    else:
        self.fail('Multiple messages contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))

def assert_message_not_contains(self, response, text):
    """ Assert that no message contains the given text. """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) > 0:
        self.fail('Message(s) contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))
9 голосов
/ 21 октября 2017

Из документации Django :

Вне шаблонов вы можете использовать get_messages ()

Итак, вы можете написать что-то вроде:

from django.contrib.messages import get_messages

[...]

messages = [m.message for m in get_messages(response.wsgi_request)]
self.assertIn('My message', messages)
3 голосов
/ 13 августа 2010

Обновление

Мой оригинальный ответ был написан, когда django был все еще 1.1 или около того.Этот ответ больше не актуален.См. ответ @ 1004 * @ daveoncode для лучшего решения.

Оригинальный ответ

Я провел эксперимент, чтобы проверить это.Я изменил настройку MESSAGE_STORAGE в одном из моих проектов на 'django.contrib.messages.storage.cookie.CookieStorage' и выполнил тест, который я написал для проверки сообщений.Это сработало.

Ключевым отличием от того, что вы делали, является способ получения сообщений.См. Ниже:

def test_message_sending(self):
    data = dict(...)
    response = self.client.post(reverse('my_view'), data)
    messages = self.user.get_and_delete_messages()

    self.assertTrue(messages)
    self.assertEqual('Hey there!', messages[0])

Этот может стоить попробовать.

0 голосов
/ 11 мая 2012

Более простая версия патовой:

class TestCaseMessagesMixture(object):
    def assertMessageCount(self, response, expect_num):
        """
        Asserts that exactly the given number of messages have been sent.
        """

        actual_num = len(response.context['messages'])
        if actual_num != expect_num:
            self.fail('Message count was %d, expected %d' %
                    (actual_num, expect_num)
                )

    def assertMessageEqual(self, response, text):
        """
        Asserts that the response includes the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text not in messages:
            self.fail(
                'No message with text "%s", messages were: %s' % 
                    (text, messages)
                )

    def assertMessageNotEqual(self, response, text):
        """
        Asserts that the response does not include the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text in messages:
            self.fail(
                'Message with text "%s" found, messages were: %s' % 
                    (text, messages)
                )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...