variable template examples python django unit-testing django-testing

python - template - ¿Cómo puedo probar los mensajes de django por unidad?



django template variable (5)

Actualizar

Mi respuesta original fue escrita cuando django todavía era 1.1 o más. Esta respuesta ya no es relevante. Ver la answer @ daveoncode para una mejor solución.

Respuesta original

Hice un experimento para probar esto. Cambié la configuración de MESSAGE_STORAGE en uno de mis proyectos a ''django.contrib.messages.storage.cookie.CookieStorage'' y ''django.contrib.messages.storage.cookie.CookieStorage'' una prueba que había escrito para verificar si había mensajes. Funcionó.

La diferencia clave de lo que estabas haciendo es la forma en que recuperé los mensajes. Vea abajo:

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])

Esto puede valer la pena intentarlo.

En mi aplicación django, intento escribir una prueba unitaria que realiza una acción y luego verifico los mensajes en la respuesta.

Por lo que puedo decir, no hay una buena manera de hacer esto.

Estoy usando el método de almacenamiento CookieStorage, y me gustaría hacer algo similar a lo siguiente:

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

El problema es que todo lo que recupero es una

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

¿Cómo puedo convertir esto en algo útil, o lo estoy haciendo todo mal?

Gracias, Daniel


De la documentación de django :

Fuera de las plantillas, puedes usar get_messages ()

Entonces, podrías escribir algo como:

from django.contrib.messages import get_messages [...] messages = [m.message for m in get_messages(response.wsgi_request)] self.assertIn(''My message'', messages)


Encontré un enfoque realmente fácil:

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

Si necesita verificar los mensajes en una respuesta que no tiene contexto, puede usar lo siguiente:

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'')

El almacenamiento alternativo no es compatible con la indexación, sin embargo, es iterable.


Esto funciona para mí (muestra todos los mensajes):

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

También aquí hay un par de métodos de utilidad que tengo en una clase de prueba heredada de TestCase de Django. Si prefiere tenerlos como funciones, elimine los argumentos self.fail() y reemplace self.fail() con un 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)))


Una versión más simple del punto muerto:

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) )