You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带LoginRequiredMixin的Django登出API匿名用户测试问题

问题分析

你的LogoutView继承了LoginRequiredMixin,未登录用户访问时,这个Mixin会自动重定向到登录页,并且在URL后带上?next=参数记录原请求地址。所以你直接用assertRedirects(response, reverse('login'))会失败,因为实际重定向的URL带了查询参数,和你预期的纯登录URL不匹配。

解决方法

下面给你几个可行的测试修改方案,任选其一即可:

方案1:只验证重定向的路径部分(推荐)

通过解析URL拆分路径和查询参数,只对比登录页的路径,忽略next参数,同时可以额外验证next参数是否正确指向原登出URL:

@pytest.mark.django_db
def test_user_logout_unauthenticated_user(client):
    url = reverse('logout')
    response = client.get(url)
    
    assert response.status_code == 302
    
    # 解析重定向URL,拆分路径和查询参数
    from urllib.parse import urlparse, parse_qs
    redirect_parsed = urlparse(response.url)
    
    # 验证重定向到登录页的路径
    assert redirect_parsed.path == reverse('login')
    
    # 可选:验证next参数是否正确指向原登出URL
    assert parse_qs(redirect_parsed.query)['next'] == [url]

方案2:直接构造带next参数的预期URL

完全匹配实际的重定向地址,适合需要严格验证完整URL的场景:

@pytest.mark.django_db
def test_user_logout_unauthenticated_user(client):
    url = reverse('logout')
    response = client.get(url)
    
    assert response.status_code == 302
    
    # 构造带next参数的预期登录URL
    expected_login_url = f"{reverse('login')}?next={url}"
    assertRedirects(response, expected_login_url)

方案3:检查Location头是否以登录URL开头

最简单的方式,只要重定向的目标路径是登录页就通过:

@pytest.mark.django_db
def test_user_logout_unauthenticated_user(client):
    url = reverse('logout')
    response = client.get(url)
    
    assert response.status_code == 302
    assert response['Location'].startswith(reverse('login'))

另外注意你的测试用例名称test_user_logout_logged_in_user和测试场景不符,建议改成test_user_logout_unauthenticated_user,更贴合“未登录用户无法访问登出API”的测试意图。

内容的提问来源于stack exchange,提问作者Parth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:10:20