16

How can I disable a specific middleware (a custom middleware I wrote) only during tests?

daveoncode
  • 18,900
  • 15
  • 104
  • 159

4 Answers4

13

Also related (since this page ranks quite high in search engines for relates queries):

If you'd only like to disable a middleware for a single case, you can also use @modify_settings:

@modify_settings(MIDDLEWARE={
    'remove': 'django.middleware.cache.FetchFromCacheMiddleware',
})
def test_my_function(self):
    pass
WhyNotHugo
  • 9,423
  • 6
  • 62
  • 70
  • Can this be used for views and specific requests as well, or is it only for test cases? – imapotatoe123 Jun 06 '19 at 11:03
  • `modify_settings` (and settings modifications more generally) are not thread-safe so you should *not* use it in production. If you are wanting to disable middleware in views, you're probably trying to solve the problem the wrong way around (e.g. can the middleware inspect the request/view to determine when it should operate?) – Kye Oct 29 '21 at 02:24
  • @KyeRussel Does it matter in testing? – Barney Szabolcs Jun 13 '22 at 16:55
11

https://docs.djangoproject.com/en/dev/topics/testing/tools/#django.test.override_settings

from django.test import TestCase, override_settings
from django.conf import settings

class MyTestCase(TestCase):

    @override_settings(
        MIDDLEWARE_CLASSES=[mc for mc in settings.MIDDLEWARE_CLASSES
                            if mc != 'myapp.middleware.MyMiddleware']
    )
    def test_my_function(self):
        pass
lampslave
  • 1,431
  • 1
  • 15
  • 20
9

There are several options:

  • create a separate test_settings settings file for testing and then run tests via:

    python manage.py test --settings=test_settings 
    
  • modify your settings.py on the fly if test is in sys.argv

    if 'test' in sys.argv:
         # modify MIDDLEWARE_CLASSES
          MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
          MIDDLEWARE_CLASSES.remove(<middleware_to_disable>)
    

Hope that helps.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • yes!!! I modified the config on the fly, since specify a new settings file is what I wanted to avoid! Thanks a lot ;) – daveoncode Aug 02 '13 at 20:59
  • 2
    @daveoncode how exactly did you implement your modification of the settings.py file on the fly? – user1847 Feb 01 '20 at 02:14
4

A nice way to handle this with a single point of modification is to create a conftest.py file at the root of Django project and the put the following contents in it:

from django.conf import settings


def pytest_configure():
    """Globally remove the your_middleware_to_remove for all tests"""
    settings.MIDDLEWARE.remove(
        'your_middleware_to_remove')

WhyNotHugo
  • 9,423
  • 6
  • 62
  • 70
user1847
  • 3,571
  • 1
  • 26
  • 35