2017-03-04 105 views
0

我有将检查POST请求与有效的数据返回与200个的状态码的HTML响应一个简单的测试情况:Django的self.client.post不发送数据,以查看与装饰

class PostRequestTestCase(TestCase): 
    def test_valid_post_request(self): 
     response = self.client.post('/foo/', data={'text': 'bar'}) 
     self.assertEqual(response.status_code, 200) 

这里是视图foo时被触发针对该请求:

logger = logging.getLogger(__name__) 

# decorator to trace enter and exit events 
enter_exit_tracer = enter_exit_Tracer(logger) 

@enter_exit_tracer 
def foo(request): 
    if request.method == 'POST': 
     # 
     print('request.POST:', request.POST) 
     # 
     # some stuff 

其中@enter_exit_tracer是一个装饰跟踪进入/退出的函数:

def enter_exit_Tracer(logger): 
    def middle(f): 
     def inner(*args, **kwargs): 
      session_string = args[-1] if 'session_key' in args[-1] else '[]' 
      logger.debug('%s Enter %s.', session_string, f.__name__) 
      result = f(*args, **kwargs) 
      logger.debug('%s Exit %s.', session_string, f.__name__) 
      return result 
     return inner 
    return middle 

事实证明,当我将此装饰器添加到foo函数时,那么通过self.client.post发送的POST数据实际上不会传递到foo。他们缺少的测试请求 - 所以我的测试失败:

DEBUG: [] Enter foo. 
request.POST: <QueryDict: {}> 
ERROR: Invalid form 
F 
====================================================================== 
FAIL: test_valid_post_request (textstat.tests.PostRequestTestCase) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/user/Pro/myapp/tests.py", line 111, in test_valid_post_request 
    self.assertEqual(response.status_code, 200) 
AssertionError: 400 != 200 

---------------------------------------------------------------------- 
Ran 1 test in 0.018s 

FAILED (failures=1) 

我们看到request.POST: <QueryDict: {}>并最终这导致ERROR: Invalid form

与此同时,当我做类似的POST请求,但通过网络浏览器一切正常 - 表单填充数据,网页呈现正常,@enter_exit_tracer按预期进行日志记录。

如果我注释掉@enter_exit_tracer装饰然后一切工作还确定,则通过测试:

request.POST: <QueryDict: {'text': ['bar']}> 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.007s 

OK 

的问题:

  • 为什么request.POST数据不会传递给视图与装饰在self.client.post的情况下请求?
  • 如果装饰器出现任何问题 - 为什么然后Web请求可以正常工作?
  • 是否可以保持装饰器并使self.client.post将数据传递给视图?
+0

记录是否被客户端调用? –

+0

是的,记录器在客户端被视为装饰器初始化时被客户端调用。例如,我们在'self.client.post'中看到'DEBUG:在输出日志中输入foo.'。 –

+0

其实我通过从装饰器的发布代码中删除args [-1] else'[]''中的'session_key'的session_string = args [-1]来简化代码。我相信这行代码不可能是pb的原因。我错了 - 这条线是pb的来源。更多细节在我的答案下面。 –

回答

0

原来,装饰在这一行有一个TypeError错误:

session_string = args[-1] if 'session_key' in args[-1] else '[]' 

所以当args[-1]str那么这不应该工作。使用str(args[-1])修复它可以解决丢失POST数据的整个问题。

虽然有线但self.client.post不会提出任何TypeErrorsession_string是以某种方式计算。而不是这个POST数据没有发送到视图没有任何错误或提示警告。数据刚刚消失。同时,当从网络浏览器发送POST请求时,相同的代码工作正常,因此错误未被注意。