-->

Django的测试 - 检查消息重定向视图(Django Testing - check messa

2019-08-31 17:47发布

我一直在写测试对于我的Django应用程序之一,并一直在寻找解决这个问题相当长的一段时间了。 我有发送使用消息的视图django.contrib.messages用于不同的情况。 视图看起来像下面这样。

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)

现在,在测试这个观点client.get的响应不包含它context包含字典messages ,因为这视图使用重定向。 对于渲染模板的观点,我们可以使用get访问消息列表messages = response.context.get('messages') 我们如何才能访问messages为重定向一个看法?

Answer 1:

使用follow=True选项,在client.get()调用,客户端将遵循重定向。 然后,您可以测试该消息是在您重定向到视图的上下文。

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)


Answer 2:

您可以使用response.wsgi_request像这样(在Django 1.10测试)get_messages():

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


Answer 3:

如果你的意见重定向并使用follow=true在你的请求,测试客户端上面不起作用。 我最后写一个辅助函数来获取与响应发送的第一个(在我的情况下,只有)消息。

@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

你这包括你的测试类中,并使用它像这样:

message = self.getmessage(response)

response是你从得到的是什么getpostClient

这是一个有点脆弱,但希望这样可以节省别人的一段时间。



Answer 4:

我使用第三方应用程序时,有同样的问题。

如果你想从返回HttpResponseRedict(从你不能访问上下文)从另一视图中的视图信息,您可以使用get_messages(request)

from django.contrib.messages import get_messages  

storage = get_messages(request)  
for message in storage:  
    do_something_with_the_message(message)  

这虽然清除消息存储,所以如果你想从模板访问后上的消息,加上:

storage.used = False


Answer 5:

替代方法嘲讽消息(并不需要遵循重定向):

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


文章来源: Django Testing - check messages for a view that redirects