I use the UUID in the url instead of the primary key. I assume, but am not sure, that this is the cause of my problem in testing my CBVs.
my view for user profile :
class ProfileView(DetailView):
slug_url_kwarg = 'uuid'
slug_field = 'uuid'
model = User
template_name = 'users/profile.html'
context_object_name = 'user_profile'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['uuid'] = self.kwargs.get("uuid")
return context
My url :
path(
route='profile/<uuid:uuid>',
view=views.ProfileView.as_view(),
name='profile',
),
I can't test get_context_data, Django tells me that my view has no "object" attribute. Maybe I need to override get_object, but my search didn't find anything.
My test :
class BaseTest(TestCase):
def setUp(self):
# Set up non-modified objects used by all test methods
self.factory = RequestFactory()
self.user2 = User.objects.create_user(
email='caroline.dupont@free.fr',
password='fhh456GG455t',
status='VALIDATED',
)
return super().setUp()
def profile_view_instance(self, test_user):
request = self.factory.get(reverse('profile', args=(test_user.uuid,)))
request.user = test_user
view = ProfileView()
view.setup(request)
return view
class ProfileViewTestCase(BaseTest):
def test_get_context_data(self):
self.client.force_login(self.user2)
context = self.profile_view_instance(self.user2).get_context_data()
self.assertIn('uuid', context)
The error :
ERROR: test_get_context_data (tests.appusers.test_views.ProfileViewTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\Developpement\projet13\tests\appusers\test_views.py", line 75, in test_get_context_data
context = self.profile_view_instance(self.user2).get_context_data()
File "D:\Developpement\projet13\users\views.py", line 66, in get_context_data
context = super().get_context_data(**kwargs)
File "D:\Developpement\projet13\venvp13\lib\site-packages\django\views\generic\detail.py", line 94, in get_context_data
if self.object:
AttributeError: 'ProfileView' object has no attribute 'object'
The profile_view_instance
is not sufficient: a DetailView
has some boilerplate logic in the .get(…)
method that is necessary to run before the .get_context_data(…)
will be triggered. It is also not a good idea to implement this logic in the test function, since then you duplicate logic, and it will be painful to update it each time you update the Django version.
Django has created a client that can be used to trigger a view. You can define a test with:
class ProfileViewTestCase(BaseTest):
def test_get_context_data(self):
self.client.force_login(self.user2)
response = self.client.get(f'/profile/{self.user2.uuid}')
context = response.context
self.assertIn('uuid', context)