Test of CreateView does not create the record

Hello everybody:
I am trying to test a Createview. But it is not working.
This is the model:

class Album(models.Model):
    coleccionista = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='albumes')
    edicion = models.ForeignKey(Edicion, on_delete=models.CASCADE, related_name='albumes')


    def __str__(self):
        return str(self.edicion.coleccion)

    def get_absolute_url(self):
        return reverse('album_detail', kwargs={'pk': self.pk})

    class Meta:
        verbose_name_plural = 'Albumes'

the url:

urlpatterns = [
    path('album/add/', AlbumCreateView.as_view(), name='album_add'),`Preformatted text`

the view:

class AlbumCreateView(LoginRequiredMixin, CreateView):
    """
    Vista que permite la creación de un álbum en blanco.
    Solo se permite la creación de un álbum por coleccion y promoción.
    Un álbum sólo puede ser creado por un usuario tipo coleccionista
    """

    model = Album
    fields = ['edicion']

    def get_form(self, *args, **kwargs):
        """
        Se garantiza que la edicion seleccionada al crear un album sea la edición en curso
        """
        form  =  super(AlbumCreateView, self).get_form(*args, **kwargs)
        queryset = Edicion.objects.filter(promocion__fecha_de_finalizacion__gte = timezone.now())
        form.fields['edicion'].queryset = queryset
        return form

and the test:

class AlbumCreateViewTest(TestCase):

    @classmethod
    def setUp(self):
        self.edicion = EdicionFactory()
        self.user = get_user_model().objects.create_user(
            username = 'camila', 
            email = 'camila@ejemplo.com',
            password = '123456',
            )

    def test_url_exists_at_correct_location(self):
        response = self.client.get("/coleccionistas/album/add/")
        self.assertTrue(self.login)
        self.assertEqual(response.status_code, 200)

    def test_album_add(self):
        self.client.login(username = 'camila', password = '123456')

        data = {
            'edicion': self.edicion  
        }
        response = self.client.post('coleccionistas/album/add', data=data)
        self.assertEqual(response.status_code, 200)

and finally, here is the test:

$ coverage run manage.py test coleccionistas.test.test_views.AlbumCreateViewTest
Creating test database for alias 'default'...
Found 2 test(s).
System check identified no issues (0 silenced).
F.
======================================================================
FAIL: test_album_add (coleccionistas.test.test_views.AlbumCreateViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\goyo\Documents\django\cromoland\coleccionistas\test\test_views.py", line 37, in test_album_add
    self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200

----------------------------------------------------------------------
Ran 2 tests in 5.667s

FAILED (failures=1)
Destroying test database for alias 'default'...
(.venv)

What does your root urls.py file look like?

You’re showing:
path('album/add/', AlbumCreateView.as_view(), name='album_add'),

but you’re trying to reference:
response = self.client.get("/coleccionistas/album/add/")

which means you would need to have coleccionistas defined as a url in your root urls.py file referencing this urls.py file.

ok ok I forgot something: the model is inside an app called coleccionistas. In the main (project_level) urlconfig, the url path looks like:

path('coleccionistas/', include('coleccionistas.urls')),  

I’d try it as an absolute URL then - with the leading /.
('/coleccionistas/album/add' instead of 'coleccionistas/album/add')

1 Like

It worked perfect! but I still have two concerns: As a Generic view, this one redirects to the view defined in the model get_absolute_url method. So why the test returns an status_code of 200 instead of 302? and last but not least, if I try to get the obejct created through the view, i get an empy queryset instead. Shouldn’t be created the record in the test database?
here is the modification I made to get the record:

        response = self.client.post('/coleccionistas/album/add/', data=data)
        alb = Album.objects.all()
        print(alb)
        self.assertEqual(response.status_code, 200)

and here is the result of the query:

Ran 2 tests in 2.836s

OK
Destroying test database for alias 'default'...
<QuerySet []>
(.venv)

I found the answer to the subject of status_code of a generic view response here
https://groups.google.com/g/django-users/c/uZ1oGmHWWB8/m/6nCPLjw_AwAJ
but I still would like to know why I can’t access the object created by the view through the ORM inside the test. Regards.