我目前正在使用Python进行Harry Percival的“测试驱动开发”,并且在将{%csrf_token%}添加到html模板中后就出现了响应问题。
由于这是测试驱动的开发,因此有一些单元测试失败。
删除{%csrf_token%}后,我会通过测试。如果代码中存在它,它将修改响应以包含意外行
<input type="hidden" name="csrfmiddlewaretoken" value="WaPf57...">
出现在原始行“
<body>
<h1>Your To-Do List</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />
{% csrf_token %}
</form>
<table id="id_list_table">
<tr><td>{{ new_item_text }}</td></tr>
</table>
</body>
在下面的单元测试中,我已经在控制台上打印了实际和预期的内容,并收到了另一行带有csrfmiddleware令牌的行。
def test_home_page_returns_correct_html(self):
request = HttpRequest()
response = home_page(request)
expected_html = render_to_string('home.html')
print('response: ', response.content.decode())
print('expected: ', expected_html)
self.assertEqual(response.content.decode(), expected_html)
是否可以将其从响应中删除,还是应该修改测试以使其包含所有预期的HTML并忽略“隐藏的” csrfmiddlewaretoken?
答案 0 :(得分:0)
与Django紧密结合的好书!错误的根源取决于csrf_token标记的功能,有关其工作原理的文档可以here找到。简而言之,每个会话都有自己的csrf令牌,以确保请求来自您的网页本身,而不仅仅是从其他地方发布到您的服务器。考虑到这一点,对页面的请求和呈现为字符串的模板应该应当具有不同的内容。
您会在书中看到很多观点,问自己是什么测试测试?对于这种情况,似乎您想检查渲染的模板是否为您期望的模板,并且为此,您可能想对reponse.templates而不是response.content.decode
进行断言。
如果您遵循该建议,它将最终看起来像这样:
self.assertEqual(response.templates[0].name, 'home.html')
答案 1 :(得分:0)
解决方案是模拟令牌生成函数,以便在您需要比较输出是否相等时它具有可预测的值。
例如,下面的代码块将确保 html 输出包含 <input type="hidden" name="csrfmiddlewaretoken" value="predicabletoken">
而不是随机令牌字符串。
from unittest import mock
from django.test import TestCase
@mock.patch('django.template.context_processors.get_token', mock.Mock(return_value='predicabletoken'))
class HomeTests(TestCase):
def test_home_page_returns_correct_html(self):
request = HttpRequest()
response = home_page(request)
expected_html = render_to_string('home.html')
print('response: ', response.content.decode())
print('expected: ', expected_html)
self.assertEqual(response.content.decode(), expected_html)