django how to assert url pattern resolves to correct class based view function
Asked Answered
W

4

11

I have a class based view

class HomePage(View):
   def get(self, request):
       return HttpResponse('<p>This is content.</p>')

and url-pattern defined as below:

urlpatterns = patterns('',
                  url(r'^$', HomePage.as_view()),
              )

To this pattern resolves to current view function, I wrote a test like this:

class HomePageTest(TestCase):

def test_root_url_resolves_to_home_page_view(self):
    found = resolve('/')
    self.assertIsInstance(found.func, HomePage)

By running this unittest I am getting following error:

self.assertIsInstance(found.func, HomePage)
AssertionError: <function HomePage at 0x7f85dd2c7840> is not an instance of <class 'web.views.HomePage'>

Any Idea how to test this case?

Weber answered 5/12, 2014 at 16:50 Comment(0)
Q
3

Resolve will return the function that is returned when calling HomePage.as_view(), and not an object of that type. However, from a quick test there may be a way that you could write this test:

self.assertEquals(found.func.func_name, HomePage.__name__)

Note that here we specify HomePage.__name__ instead of 'HomePage' because this will get picked up if the name of the class is changed using refactoring tools.

The downside of this is, should you have wired up a view class with the same name but from a different module, this unit test would not fail. Of course this is more of a risk with a generic view class name such as HomePage but should be less of a risk with other view classes.

Qianaqibla answered 5/12, 2014 at 17:43 Comment(3)
But I was wondering if I could use assert for particular instance of class only. That means not using hard coded class name.Weber
It's not ideal I know, but unfortunately I'm not sure how you would get the class object from the function returned by resolve. If you want to use the type object in the assertion (so that it would handle refactorings) you could use HomePage.__name__ instead in the assertion.Qianaqibla
I had done same way like you specified but raised this question to make sure if Django provides more better way to this. ThanksWeber
W
21

Django's View.as_view() creates a function with a view_class attribute which points to the class-based view. So use:

self.assertEquals(found.func.view_class, HomePage)

Avoids the problem of two class-based views in different modules with the same name.

Wommera answered 20/5, 2017 at 5:45 Comment(0)
D
4

May be it's an old question, but in django>=1.8 assertion like

self.assertEquals(found.func.func_name, HomePage.__name__)

AttributeError: 'function' object has no attribute 'func_name' so I changed it to

self.assertEqual(found.func.__name__, HomePage.__name__)
Doll answered 16/9, 2015 at 6:34 Comment(0)
Q
3

Resolve will return the function that is returned when calling HomePage.as_view(), and not an object of that type. However, from a quick test there may be a way that you could write this test:

self.assertEquals(found.func.func_name, HomePage.__name__)

Note that here we specify HomePage.__name__ instead of 'HomePage' because this will get picked up if the name of the class is changed using refactoring tools.

The downside of this is, should you have wired up a view class with the same name but from a different module, this unit test would not fail. Of course this is more of a risk with a generic view class name such as HomePage but should be less of a risk with other view classes.

Qianaqibla answered 5/12, 2014 at 17:43 Comment(3)
But I was wondering if I could use assert for particular instance of class only. That means not using hard coded class name.Weber
It's not ideal I know, but unfortunately I'm not sure how you would get the class object from the function returned by resolve. If you want to use the type object in the assertion (so that it would handle refactorings) you could use HomePage.__name__ instead in the assertion.Qianaqibla
I had done same way like you specified but raised this question to make sure if Django provides more better way to this. ThanksWeber
H
0

I did it another way because Valentjedi did not work for me; I did .:

class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.view_name, "home")

Hope it helps

Hester answered 24/2, 2018 at 16:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.