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:

  1. An instance of AdminSite:

     from django.contrib.admin.sites import AdminSite
    
  2. Your model class and corresponding ModelAdmin (sub)class:

     from my_app.models import MyModel
     from my_app.admin import MyModelAdmin
    
  3. 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.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)