I have a Django context processor that puts the name of the current URL into the template context:
def url_name(request):
url_name = False
if request.resolver_match:
url_name = request.resolver_match.url_name
return {"url_name": url_name}
This works - if I visit /
then {{ url_name }}
in the template will display "home" because I have a URL pattern like:
path("", HomeView.as_view(), name="home"),
I would like to write a unittest for this context processor. I could do it like this:
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")
That succeeds, but I'd like to unitttest the url_name()
method on its own, outside of the response cycle.
I've tried this:
class URLNameTestCase(TestCase):
def test_url_name(self):
request = RequestFactory().get("/")
context = url_name(request)
self.assertEqual(context["url_name"], "home")
But that fails because, in this situation, within url_name()
, request.resolver_match
is None
. Why is that?
since you try to get urlname by urlpath you should link your request with some view, you can do it to set "resolver_match" attribute like that:
from django.urls import resolve
...
class URLNameTestCase(TestCase):
def test_url_name(self):
request = RequestFactory().get("/")
request.resolver_match = resolve("/")
...
You create a request using a RequestFactory but it doesn't mean that your request is linked with any view, to link your request with some view you need to set resolver_match to your request.
Read more: