Testing custom Django middleware without using Django itself
The problem is that you are not calling neither the constructor of MyMiddleware
neither invoking the __call__
magic method by invoking the instance of a MyMiddleware
object.
There are many ways to test the behaviour that you described, I can think of this one:
First, I slightly modified your example to be self contained:
class MyMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.new_attribute = some_function_returning_some_object()
response = self.get_response(request)
return response
def some_function_returning_some_object():
return 'whatever'
Next, I created the tests by actually creating the Middleware object and invoking the newly created object as it was a function (so __call__
is run)
from mock import patch, Mock
from middle import MyMiddleware
import unittest
class TestMiddleware(unittest.TestCase):
@patch('middle.MyMiddleware')
def test_init(self, my_middleware_mock):
my_middleware = MyMiddleware('response')
assert(my_middleware.get_response) == 'response'
def test_mymiddleware(self):
request = Mock()
my_middleware = MyMiddleware(Mock())
# CALL MIDDLEWARE ON REQUEST HERE
my_middleware(request)
assert request.new_attribute == 'whatever'
Here there are some useful links:
Difference between __call__ and __init__ in another SO question: __init__ or __call__?
Where to patch from the python docs: https://docs.python.org/3/library/unittest.mock.html#where-to-patch
pytest docs: http://docs.pytest.org/en/latest/contents.html
ipdb intro, useful for debugging: https://www.safaribooksonline.com/blog/2014/11/18/intro-python-debugger/