Django csrf 令牌正在修改预期输出并导致单元测试失败

我目前正在使用 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?


交互式爱情
浏览 155回答 2
2回答

呼唤远方

很棒的书,可以用来学习 Django!您的错误来源基于 csrf_token 标签的功能,可以在此处找到有关其工作原理的文档。简而言之,每个会话都有自己的 csrf 令牌,以确保请求来自您的网页本身,而不仅仅是从其他地方发布到您的服务器。考虑到这一点,对页面的请求和呈现为字符串的模板应该具有不同的内容。你会在那本书中看到很多的一点是问自己这个测试是什么?对于这种情况,您似乎想检查所呈现的模板是否是您期望的模板,为此您可能希望对reponse.templates而不是 进行断言response.content.decode。如果您遵循该建议,它将最终看起来像:&nbsp;&nbsp;&nbsp;&nbsp;self.assertEqual(response.templates[0].name,&nbsp;'home.html')

HUX布斯

解决方案是模拟令牌生成函数,以便在需要比较输出的相等性时它具有可预测的值。例如,下面的代码块将确保 html 输出包含<input type="hidden" name="csrfmiddlewaretoken" value="predicabletoken">而不是随机令牌字符串。from unittest import mockfrom django.test import TestCase@mock.patch('django.template.context_processors.get_token', mock.Mock(return_value='predicabletoken'))class HomeTests(TestCase):&nbsp; def test_home_page_returns_correct_html(self):&nbsp; &nbsp; request = HttpRequest()&nbsp; &nbsp; response = home_page(request)&nbsp; &nbsp; expected_html = render_to_string('home.html')&nbsp; &nbsp; print('response: ', response.content.decode())&nbsp; &nbsp; print('expected: ', expected_html)&nbsp; &nbsp; self.assertEqual(response.content.decode(), expected_html)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python