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

Django中reverse_lazy模拟失效求助:无需目标URL完成测试

问题描述

测试Django用户注册视图UserRegisterView时,希望通过mockreverse_lazy跳过创建user-register-first-success对应的URL和视图,但尝试了两种patch方式都无效,依然抛出NoReverseMatch错误。目前通过临时添加URL解决,求无需创建实际URL的正确mock方案。

相关代码

views.py

# views.py
from django.contrib.auth import get_user_model
from django.urls import reverse_lazy
from django.views import generic

from accounts import forms

User = get_user_model()


class UserRegisterView(generic.FormView):
    model = User
    template_name = 'accounts/register_form.html'
    form_class = forms.UserRegisterForm
    success_url = reverse_lazy('accounts:user-register-first-success')

    def form_valid(self, form):
        form.save()
        return super().form_valid(form)

test_views.py

# test_views.py
from unittest.mock import patch

from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse

User = get_user_model()


class UserRegisterViewTest(TestCase):
    def setUp(self) -> None:
        self.url = reverse('accounts:user-register')
        self.data = {
            'email': 'rick.sanchez@test.com',
            'password': 'qwe123!@#',
            'confirmed_password': 'qwe123!@#',
        }
    @patch('accounts.views.reverse_lazy', return_value='mock_url')
    def test_view_redirects_to_correct_page_POST(self, mock):

        response = self.client.post(self.url, self.data)

        self.assertRedirects(response, mock('accounts:user-register-first-success'))

    @patch('django.urls.reverse_lazy', return_value='mock_url')
    def test_view_redirects_to_correct_page_POST_(self, mock):
        response = self.client.post(self.url, self.data)

        self.assertRedirects(response, mock('accounts:user-register-first-success'))

错误信息

File "/home/branya/Документи/My Projects/Django/hotel/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 848, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'user-register-first-success' not found. 'user-register-first-success' is not a valid view function or pattern name.
解决方案

问题根源

UserRegisterView的success_url是类属性,在views模块被导入时就会执行reverse_lazy生成值。而你的测试是在模块导入完成后才patchreverse_lazy,此时success_url已经被赋值为真实的URL解析结果(解析失败就报错),所以mock根本没生效。

三种可行方案

方案1:直接替换视图类的success_url属性

不需要mockreverse_lazy,测试时直接覆盖类属性:

def test_view_redirects_to_correct_page_POST(self):
    UserRegisterView.success_url = 'mock_url'
    response = self.client.post(self.url, self.data)
    self.assertRedirects(response, 'mock_url')

方案2:用patch.object直接mock视图类的success_url

这种方式更简洁,直接针对类属性进行patch:

from unittest.mock import patch

class UserRegisterViewTest(TestCase):
    # ... 其他代码不变 ...

    @patch.object(UserRegisterView, 'success_url', 'mock_url')
    def test_view_redirects_to_correct_page_POST(self):
        response = self.client.post(self.url, self.data)
        self.assertRedirects(response, 'mock_url')

方案3:在模块导入前patchreverse_lazy(验证调用参数)

如果需要验证reverse_lazy是否被传入了正确的参数,可以在views模块导入前就patchreverse_lazy,确保类属性初始化时使用mock后的函数:

from unittest.mock import patch

@patch('django.urls.reverse_lazy', return_value='mock_url')
class UserRegisterViewTest(TestCase):
    @classmethod
    def setUpClass(cls):
        # 先patch再导入views模块
        super().setUpClass()
        from accounts import views
        cls.UserRegisterView = views.UserRegisterView

    def setUp(self) -> None:
        self.url = reverse('accounts:user-register')
        self.data = {
            'email': 'rick.sanchez@test.com',
            'password': 'qwe123!@#',
            'confirmed_password': 'qwe123!@#',
        }

    def test_view_redirects_to_correct_page_POST(self, mock_reverse_lazy):
        response = self.client.post(self.url, self.data)
        self.assertRedirects(response, 'mock_url')
        # 验证reverse_lazy的调用参数是否正确
        mock_reverse_lazy.assert_called_once_with('accounts:user-register-first-success')

内容的提问来源于stack exchange,提问作者Богдан Тимченко

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:15:07