Testing custom Django middleware without using Django itself
我已经用1.10样式对我的自定义django中间件进行了编码,类似于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MyMiddleware(object): def __init__(self, get_response): self.get_response = get_response # some initialization stuff here def __call__(self, request): # Code executed before view functions are called. # Purpose of this middeware is to add new attribute to request # In brief: request.new_attribute = some_function_returning_some_object() response = self.get_response(request) # Code to be executed for each request/response after # the view is called. return response |
注意,这个中间件作为一个单独的python模块受到威胁,它不属于我项目中的任何特定应用程序,而是通过pip生活在外部并像其他包一样安装。它本身不工作,但只有安装在Django应用程序中。
它工作得很好,不过,我想测试一下。到目前为止,我在
1 2 3 4 5 6 7 | from my_middleware_module import MyMiddleware # some @patches def test_mymiddleware(): request = Mock() assert hasattr(request, 'new_attribute') is False # passes obviously # CALL MIDDLEWARE ON REQUEST HERE assert hasattr(request, 'new_attribute') is True # I want it to pass |
我不知道如何调用
问题是,您既不调用EDOCX1的构造函数(0),也不通过调用
有很多方法可以测试您描述的行为,我可以想到这一个:
首先,我稍微修改了您的示例,使其独立:
1 2 3 4 5 6 7 8 9 10 11 12 | 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() import ipdb; ipdb.set_trace() response = self.get_response(request) return response def some_function_returning_some_object(): return 'whatever' |
接下来,我通过实际创建中间件对象并调用新创建的对象(因为它是一个函数)来创建测试(因此运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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' |
这里有一些有用的链接:
在另一个问题中,你的呼叫和初始呼叫之间的区别是:初始呼叫还是初始呼叫?
从python文档修补的位置:https://docs.python.org/3/library/unittest.mock.html修补的位置
pytest文档:http://docs.pytest.org/en/latest/contents.html
IPDB简介,用于调试:https://www.safaribooksonline.com/blog/2014/11/18/intro-python-debugger/