在 Django context_processor 中测试 request.resolver_match

Testing request.resolver_match in a Django context_processor

我有一个 Django 上下文处理器,它将当前 URL 的名称放入模板上下文中:

def url_name(request):
    url_name = False
    if request.resolver_match:
        url_name = request.resolver_match.url_name
    return {"url_name": url_name}

这行得通 - 如果我访问 /,那么模板中的 {{ url_name }} 将显示“主页”,因为我有一个 URL 模式,例如:

path("", HomeView.as_view(), name="home"),

我想为此上下文处理器编写一个单元测试。我可以这样做:

from django.test import Client, RequestFactory, TestCase
from myapp.context_processors import url_name

class URLNameTestCase(TestCase):
    def test_url_name(self):
        response = Client().get("/")
        self.assertEqual(response.context["url_name"], "home")

成功了,但我想在响应周期之外单独测试 url_name() 方法。

我试过这个:

class URLNameTestCase(TestCase):
    def test_url_name(self):
        request = RequestFactory().get("/")
        context = url_name(request)
        self.assertEqual(context["url_name"], "home")

但这失败了,因为在这种情况下,url_name()request.resolver_matchNone。这是为什么?

既然你试图通过 urlpath 获取 urlname,你应该 link 你的请求有一些观点,你可以这样做来设置“resolver_match”属性:

from django.urls import resolve

...

class URLNameTestCase(TestCase):
    def test_url_name(self):
        request = RequestFactory().get("/")
        request.resolver_match = resolve("/")
...

您使用 RequestFactory 创建了一个请求,但这并不意味着您的请求是 link 与任何视图一起编辑的,link 您的请求与您需要设置的某些视图 resolver_match 根据您的要求。

阅读更多:

Link 1

Link 2