vistas template por pasar parametros examples example enviar bootstrap django redirect testing messages django-context

template - Pruebas de Django: compruebe los mensajes para una vista que redirige



views django example (5)

He estado escribiendo pruebas para una de mis aplicaciones de django y he estado buscando solucionar este problema desde hace bastante tiempo. Tengo una vista que envía mensajes usando django.contrib.messages para diferentes casos. La vista se parece a la siguiente.

from django.contrib import messages from django.shortcuts import redirect import custom_messages def some_view(request): """ This is a sample view for testing purposes. """ some_condition = models.SomeModel.objects.get_or_none( condition=some_condition) if some_condition: messages.success(request, custom_message.SUCCESS) else: messages.error(request, custom_message.ERROR) redirect(some_other_view)

Ahora, mientras se prueba esta vista, la respuesta de client.get no contiene el diccionario de context que contiene los messages ya que esta vista utiliza una redirección. Para las vistas que representan plantillas, podemos obtener acceso a la lista de messages = response.context.get(''messages'') utilizando messages = response.context.get(''messages'') . ¿Cómo podemos obtener messages acceso para una vista que redirige?


Método alternativo de mensajes de burla (no es necesario seguir la redirección):

from mock import ANY, patch from django.contrib import messages @patch(''myapp.views.messages.add_message'') def test_some_view(self, mock_add_message): r = self.client.get(''/some-url/'') mock_add_message.assert_called_once_with(ANY, messages.ERROR, ''Expected message.'') # or assert_called_with, assert_has_calls...


Puede usar get_messages () con response.wsgi_request como este (probado en Django 1.10):

from django.contrib.messages import get_messages ... def test_view(self): response = self.client.get(''/some-url/'') # you don''t need follow=True self.assertRedirects(response, ''/some-other-url/'') # each element is an instance of django.contrib.messages.storage.base.Message all_messages = [msg for msg in get_messages(response.wsgi_request)] # here''s how you test the first message self.assertEqual(all_messages[0].tags, "success") self.assertEqual(all_messages[0].message, "you have done well")


Si sus vistas están redireccionando y usa follow=true en su solicitud al cliente de prueba, lo anterior no funcionará. Terminé escribiendo una función de ayuda para recibir el primer mensaje (y, en mi caso, solo) enviado con la respuesta.

@classmethod def getmessage(cls, response): """Helper method to return message from response """ for c in response.context: message = [m for m in c.get(''messages'')][0] if message: return message

Incluyes esto dentro de tu clase de prueba y lo usas así:

message = self.getmessage(response)

Donde la response es lo que obtienes de una get o post en un Client .

Esto es un poco frágil pero con suerte le ahorra a alguien más tiempo.


Tuve el mismo problema al usar una aplicación de terceros.

Si desea obtener los mensajes de una vista que devuelve un HttpResponseRedict (desde el cual no puede acceder al contexto) desde otra vista, puede usar get_messages(request)

from django.contrib.messages import get_messages storage = get_messages(request) for message in storage: do_something_with_the_message(message)

Sin embargo, esto borra el almacenamiento de mensajes, por lo que si desea acceder a los mensajes desde una plantilla más adelante, agregue:

storage.used = False


Use la opción follow=True en la llamada client.get() , y el cliente seguirá la redirección. Luego puede probar que el mensaje se encuentra en el contexto de la vista a la que redirigió.

def test_some_view(self): # use follow=True to follow redirect response = self.client.get(''/some-url/'', follow=True) # don''t really need to check status code because assertRedirects will check it self.assertEqual(response.status_code, 200) self.assertRedirects(response, ''/some-other-url/'') # get message from context and check that expected text is there message = list(response.context.get(''messages''))[0] self.assertEqual(message.tags, "success") self.assertTrue("success text" in message.message)