Overriding decorator during unit test in python
我有一个基于django类的视图,我正在装饰。 不幸的是,装饰器进行外部调用以进行状态检查,这超出了单元测试应该做的范围,所以我想覆盖装饰器在单元测试期间什么都不做。 这是我的装饰者:
decorators.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | def status_check(func): @wraps(func) def wrapped(request, *args, **kwargs): uri = settings.SERVER_URI status_code = None bad_status = [404, 500] try: response = requests.head(uri) except requests.ConnectionError as err: LOGGER.error('Server is hosed! Oh Noes! Error: %s ' % (err)) raise Http404 except Exception as err: LOGGER.error('Some crazy stuff is happening. Its Bad. ' 'Error: %s' % (err)) raise Http404 status_code = response.status_code if not status_code or status_code in bad_status: LOGGER.error('Awww Snap! Server is not happy: %s' % (status_code)) raise Http404 return func(request, *args, **kwargs) return wrapped |
views.py
1 2 3 4 | class HandleFoo(DetailView): @method_decorator(status_check) def post(self, request): # do stuff here |
tests.py
1 2 3 4 5 6 7 8 | class RunTest(TestCase): def test_post(self): post_data = json.dumps({'stuff': 'vodka', 'things': 'tonic'}) resp = self.client.post(self.foo_uri, post_data, content_type='application/json', ) self.assertEqual(resp.status_code, 200) |
那么我有没有办法覆盖装饰器或者我可以完全绕过它? 我对此非常难过。
编辑
尝试使用krak3n中的以下内容嘲笑请求:
1 2 3 4 | @patch('app.views.method_decorator.status_check', lambda func: func) @patch('app.views.status_check', lambda func: func) @patch('app.decorators.status_check', lambda func: func) @patch('app.views.HandleFoo.post', lambda func: func) |
到目前为止,最后一个方法让我最接近,但它最终会抛出一个堆栈跟踪:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | Traceback (most recent call last): File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/mock.py", line 1201, in patched return func(*args, **keywargs) File"/Users/squiddly/projects/tests/app/tests.py", line 165, in test_post content_type='application/json', File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/client.py", line 463, in post response = super(Client, self).post(path, data=data, content_type=content_type, **extra) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/client.py", line 297, in post return self.request(**r) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/client.py", line 406, in request response = self.handler(environ) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/client.py", line 111, in __call__ response = self.get_response(request) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/core/handlers/base.py", line 178, in get_response response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/core/handlers/base.py", line 224, in handle_uncaught_exception return callback(request, **param_dict) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view response = view_func(request, *args, **kwargs) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/views/defaults.py", line 41, in server_error return http.HttpResponseServerError(template.render(Context({}))) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 140, in render return self._render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/utils.py", line 65, in instrumented_test_render return self.nodelist.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 830, in render bit = self.render_node(node, context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node return node.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/loader_tags.py", line 124, in render return compiled_parent._render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/utils.py", line 65, in instrumented_test_render return self.nodelist.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 830, in render bit = self.render_node(node, context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node return node.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/loader_tags.py", line 156, in render return self.render_template(self.template, context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/loader_tags.py", line 138, in render_template output = template.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 140, in render return self._render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/test/utils.py", line 65, in instrumented_test_render return self.nodelist.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 830, in render bit = self.render_node(node, context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node return node.render(context) File"/Users/squiddly/envs/testenv/lib/python2.7/site-packages/django/template/base.py", line 1185, in render _dict = func(*resolved_args, **resolved_kwargs) File"/Users/squiddly/projects/tests/app/templatetags/app_extras.py", line 40, in get_data if request.session.has_key('start_time'): AttributeError: 'str' object has no attribute 'session' |
我想你必须进入
您可以使用
1 2 3 | @patch('python.path.to.decorator', new_callable=PropertyMock) def my_test(self, decorator_mock): # your test code |
给那个旋转。
您可以在此处阅读
编辑
也许试试:
1 2 3 | @patch('python.path.to.decorator', lambda: func: func) def my_test(self): # your test code |
这应该理论上修补装饰器,所以它只返回函数而不是你在