testing admin.ModelAdmin in django
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 pass a request (i.e. the third ingredient) with a valid user, in addition to the model instance:
super_user = User.objects.create_superuser(username='super', email='[email protected]',
password='pass')
my_model_admin.save_model(obj=MyModel(), request=MockRequest(user=super_user),
form=None, change=None)
# some test assertions here
An example of the MockRequest
is defined below. 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.
class MockRequest(object):
def __init__(self, user=None):
self.user = user
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())
# ...
I had a similar problem so I wrote a tiny little helper here: https://github.com/metzlar/djest