I am trying to find out the best way for testing admin.ModelAdmin
in admin.py
. Specifically I am overriding the save_model()
function which I want to test. From the research I have done, the only solution I have found was writing a request/response test and then query the database.
Check out Django's ModelAdminTests
for examples.
As suggested in Udi's answer, we can study Django's own ModelAdmin tests, to determine the basic ingredients for a ModelAdmin
test. Here's a summary:
Basic ingredients
In addition to the Django TestCase
stuff, the basic ingredients are:
An instance of
AdminSite
:from django.contrib.admin.sites import AdminSite
Your model class and corresponding
ModelAdmin
(sub)class:from my_app.models import MyModel from my_app.admin import MyModelAdmin
Optionally, depending on your needs, a (mock) request and/or form.
Recipe
The first two ingredients are required to create an instance of your (custom) ModelAdmin
:
my_model_admin = MyModelAdmin(model=MyModel, admin_site=AdminSite())
Based on the ModelAdmin source, the default save_model
implementation only requires an instance of your model, so it can be called, for example, as follows:
my_model_admin.save_model(obj=MyModel(), request=None, form=None, change=None)
# some test assertions here
It all depends on what your save_model
does, and what you want to test.
Suppose your save_model
checks user permissions, then you would need to provide a request
(i.e. the third ingredient) with a valid user, in addition to the model instance:
from unittest.mock import Mock
...
my_user = User.objects.create(...)
my_model_admin.save_model(
obj=MyModel(), request=Mock(user=my_user), form=None, change=None
)
# some test assertions here
Here we use unittest.mock.Mock
to create a mock-request. Based on the Django test source, a minimal request
consists of a Python object
with a user
attribute.
The user
attribute may refer to a mock user, or an actual instance of your AUTH_USER_MODEL
, depending on your needs. An alternative would be to use django.test.RequestFactory.
This basic approach applies to the other ModelAdmin
methods as well.
Check out Django's ModelAdminTests
for examples.
You can specify custom modelform for modeladmin then simply test this modelform ;)
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
forms
class SomeModelForm(forms.ModelForm):
class Meta:
model = SomeModel
admin
class SomeModelAdmin(admin.ModelAdmin):
form = SomeModelForm
admin.site.register(SomeModel, SomeModelAdmin)
tests
class TestSomeModel(TestCase):
def test_form(self):
form = SomeModelForm(**kwargs)
self.assertTrue(form.is_valid())
# ...
To test if the search does not lead to server errors (i.e. because search_fields
are not correct) you can use the following code:
from django.contrib import admin
from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
class TestModelAdmins(TestCase):
def test_search_fields(self):
user_1 = User(
username="user1",
first_name="User",
last_name="One",
email="[email protected]",
password="superSecurePasswordFromStackoverflow",
is_superuser=True,
is_staff=True,
)
user_1.full_clean()
user_1.save()
self.client.force_login(user_1)
for model_class, admin_class in admin.site._registry.items():
with self.subTest(model_class._meta.model_name):
path = reverse("admin:%s_%s_changelist" % (model_class._meta.app_label, model_class._meta.model_name))
response = self.client.get(path + "?q=blub")
self.assertEqual(response.status_code, 200)
© 2022 - 2024 — McMap. All rights reserved.