I'm adding unit tests to my blog and I can't pass the test that it should pass .
The proof is this:
from django.test import TestCase
from django.urls import resolve
from apps.blog.views 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 apps.blog.models import Entry
class EntryList(ListView):
model = Entry
And in the file urls.py
the root points to that class:
from django.conf.urls import url
urlpatterns = [
url(r'^$', EntryList.as_view(), name='index')
]
When running this I get this error:
$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_la_portada_apunta_a_entrylist_view (src.apps.blog.tests.ApiRootTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Volumes/datos/Proyectos/nspaces/src/apps/blog/tests.py", 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 don't understand why two instances of the class are created EntryList
, instead of just one, which would make my test pass Ok.
What changes do I need to make to pass the unit test?
Plus: what am I doing wrong?
If you take a good look at what your unit test is returning, you will realize that it is comparing two different memory objects:
Because 80x11010dd0 is different from 0x10fe1dea0.
It seems to me that there are two ways to solve your problem. One, but it is not correct, is to use the method
isinstance
that, instead of comparing if the memory address is the same, will check if the two 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 within it the mock function. If you "mock" your function, mock lets you know if your mocked function was called (executed) once or many times. This is the way it is done:
You can see more about mock in mock tuto and official documentation of mock in python 3