It's not exactly crystal clear how to test the functionalities that you add to django admin without diving into the source code of Django. So here are a few tips and snippets that'll help.

Testing ModelAdmin methods

When you come to the point that you need to override any of the ModelAdmin methods how do you go about testing them? You could do it through the client and make a POST request to the view that saves the model, but that is a lot of work.

Most of the ModelAdmin methods require a request. So if we mock that out, we can quite easily test the method without taking much else into account.

from django.contrib.admin.sites import AdminSite from django.contrib.messages.storage.fallback import FallbackStorage from django.test import TestCase from django.test import RequestFactory class MockSuperUser : def has_perm ( self , perm ): return True request_factory = RequestFactory () request = request_factory . get ( '/admin' ) request . user = MockSuperUser () # If you need to test something using messages setattr ( request , 'session' , 'session' ) messages = FallbackStorage ( request ) setattr ( request , '_messages' , messages ) class MyAdminTest ( Testcase ): def setUp ( self ): site = AdminSite () self . admin = MyAdmin ( MyModel , site ) def test_delete_model ( self ): obj = MyModel . objects . get ( pk = 1 ) self . admin . delete_model ( request , obj ) deleted = MyModel . objects . filter ( pk = 1 ) . first () self . assertEqual ( deleted , None )

This way you don't need to focus much at all on the request argument and can focus on asserting on any side effects or other functionalities that your modified ModelAdmin methods does.

Testing a file upload in Django admin

If you're about to test an admin view where you upload some file, you'll need to use the test Client that django has in the TestCase class. Django has some documentation around how that works.

The post method takes a path and a dictionary of DATA arguments. If one of these arguments is a file like object you'll be able to access it as request.FILES in the response.

To test your file upload it would look like this.

from django.test import TestCase from io import BytesIO # you could use StringIO as well class FileTest ( TestCase ): def setUp ( self ): # the file in this case is modeled as a simple csv self . file = BytesIO ( b 'model_id

1

2

' ) def test_file_upload ( self ): # each admin url consits of the following three things # the app name, the name of the model and the name of the view url = reverse ( 'admin:appname_modelname_viewname' ) resp = self . client ( url , { 'form_filefield' : self . file }) # Here you'll want to do extra assertions, ie are you # saving the file in a model, streaming something back in # streamingresponse or doing something else. self . assertEqual ( resp . status_code , 200 )

The file like object you also be a file handler as in this example.

with open ( 'some_file.csv' ) as f : self . client . post ( url , { 'form_filefield' : f })

Though I find that if you just want to test something not too complex it's easier to use either BytesIO or StringIO and construct the file content in place rather than having file fixtures.

Do you find that there are other tricky bits testing the django admin, tweet me and I'll add it!