Django单元测试如何模拟HTMX GET请求测试片段返回逻辑
问题根因
测试失败的核心原因是你构造HTMX请求头的传参方式错误。你当前代码中把headers字典用**解包为关键字参数传给self.client.get(),这些参数会被识别成URL查询参数,根本不会被放到HTTP请求头里,所以django-htmx中间件检测不到HTMX标识,request.htmx判断始终为False,视图自然返回完整页面模板。
django-htmx通过请求头中的HX-Request: true标识HTMX请求,只要按照Django测试客户端的规则正确传入这个请求头即可。
修复方案
根据你使用的Django版本选对应写法即可:
Django 4.0及以上版本
Django 4.0开始测试客户端原生支持headers参数接收请求头字典,不需要额外加前缀,也不要解包字典,直接传入即可:
from django.test import TestCase class TestRequests(TestCase): def test_page(self): response = self.client.get('/') self.assertTemplateUsed(response, 'page.html') def test_fragment(self): headers = {'HX-Request': 'true'} # 直接将headers字典传给headers参数,不要用**解包 response = self.client.get('/', headers=headers) self.assertTemplateUsed(response, 'fragment.html')
Django 3.2及更早版本
低版本Django测试客户端没有专门的headers参数,自定义HTTP头需要作为关键字参数传入,且参数名必须添加HTTP_前缀,头名中的横杠替换为下划线:
from django.test import TestCase class TestRequests(TestCase): def test_page(self): response = self.client.get('/') self.assertTemplateUsed(response, 'page.html') def test_fragment(self): # 直接传HTTP_HX_REQUEST关键字参数 response = self.client.get('/', HTTP_HX_REQUEST='true') self.assertTemplateUsed(response, 'fragment.html')
排查注意点
如果修改后依然不生效,先确认两个基础配置:
- 确认
settings.py的MIDDLEWARE列表中已经添加了django_htmx.middleware.HtmxMiddleware,缺少这个中间件的话request.htmx属性不会生效 HX-Request头只要传非空值就能被识别,和HTMX官方行为保持一致传字符串'true'即可
内容的提问来源于stack exchange,提问作者QuiteClose
相关产品推荐
相关产品推荐

