如何对Django消息进行单元测试?
在我的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>
我该如何把这个变得有用,或者我是不是做错了什么?
谢谢,
丹尼尔
7 个回答
19
这个方法对我有效(可以显示所有信息):
print [m.message for m in list(response.context['messages'])]
另外,这里有几个我在一个测试类中用到的工具方法,这个测试类是从Django的TestCase继承来的。如果你想把它们变成普通的函数,只需要去掉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)))
30
来自 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)
132
我找到了一种非常简单的方法:
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')
备用存储不支持索引,但它是可以遍历的。