我正在尝试在Django中执行单元测试。我在index.html
中有以下表格:
<form method=POST>
{% csrf_token %}
<input name=itemT>
</form>
我正在测试视图是否正确呈现模板:
views.py
def homePage(request):
return render(request, 'index.html')
tests.py:
request = HttpRequest()
response = homePage(request)
if response:
response = response.content.decode('UTF-8')
expectedHTML = render_to_string('index.html')
self.assertEqual(response, expectedHTML)
response
有一个带有csrf标记的隐藏输入字段;但是,expectedHTML
没有({% csrf_token %}
处只有一个空行)。所以断言总是失败。
是否可以让render_to_string()
生成csrf输入字段?如果是,response
的令牌是否与expectedHTML
的令牌相同?
或者,有没有办法忽略输入字段,以便测试成功?
答案 0 :(得分:35)
要在使用render_to_string
时使csrf令牌正常工作,您需要提供request
对象以便上下文处理器运行。
在Django 1.8+中,您可以简单地将请求作为参数传递
return render_to_string('index.html', request=request)
在早期版本中,您可以使用RequestContext
。
from django.template import RequestContext
render_to_string('index.html', context_instance=RequestContext(request))
答案 1 :(得分:19)
不幸的是,Alasdair的答案不适用于Django 1.10
,因为csrf_token
会对每个请求进行更改。请参阅适用于1.10的this gist。 (改变代码以修复原始要点中的拼写错误)
class HomePageTest(TestCase):
@staticmethod
def remove_csrf(html_code):
csrf_regex = r'<input[^>]+csrfmiddlewaretoken[^>]+>'
return re.sub(csrf_regex, '', html_code)
def assertEqualExceptCSRF(self, html_code1, html_code2):
return self.assertEqual(
self.remove_csrf(html_code1),
self.remove_csrf(html_code2)
)
答案 2 :(得分:4)
答案 3 :(得分:0)
从 Django 2 开始,您可以这样做:
html = render_to_string('my_template.html', context, request=request)