Pass a unit test of views based on Django classes


I'm adding unit tests to my blog and I can not pass the test that should happen .

The test is this:

from django.test import TestCase
from django.urls import resolve
from import EntryList

class ApiRootTest(TestCase):
    def test_la_portada_apunta_a_entrylist_view(self):
        found = resolve('/')
        self.assertEqual(found.func, EntryList.as_view())

It's very simple, I want to prove that the root points to the CBV EntryList, which is more or less like this:

from django.views.generic import ListView
from import Entry

class EntryList(ListView):
    model = Entry

And in the file the root points to that class:

from django.conf.urls import url

    urlpatterns = [
        url(r'^$', EntryList.as_view(), name='index')

When executing the east, I get this error:

 $ python test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
FAIL: test_la_portada_apunta_a_entrylist_view (
Traceback (most recent call last):
  File "/Volumes/datos/Proyectos/nspaces/src/apps/blog/", line 11, in test_la_portada_apunta_a_entrylist_view
    self.assertEqual(found.func, EntryList.as_view())
AssertionError: <function EntryList at 0x11010dd08> != <function EntryList at 0x10fe1dea0>

Ran 1 test in 0.004s

I do not understand why two instances of class EntryList are created, instead of just one, which would make my test pass OK.

What changes should I make to pass the unit test?

Plus: What am I doing wrong?

asked by toledano 06.08.2017 в 00:46

1 answer


If you observe well what your unit test is returning, you will realize that you are comparing two different memory objects:

<function EntryList at 80x11010dd0> != <function EntryList at 0x10fe1dea0>

Because 80x11010dd0 is different from 0x10fe1dea0.

I think there are two ways to solve your problem. One, but it is not the right thing to do, is to use the isinstance method that, instead of comparing if the memory address is the same, it will be fixed if both are instances of the same class. This would be:         self.assertEqual (isinstance (EntryList.as_view (), found.func))

But, in reality, what you want to test in your test is if your function has been called, that is, if it has been executed when you use that view. For this there is the unittest library and inside it the mock function. If you "mock" your function, mock lets you know if your mocked feature was called (executed) once or many times. This is done like this:

def test_la_portada_apunta_a_entrylist_view(self):
        mocked_view = mock.patch('')
        found = resolve('/')

You can see more about mock at mock tuto and official mock documentation in python 3

answered by 06.08.2017 / 02:00