2017-03-04 28 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請求時,相同的代碼工作正常,因此錯誤未被注意。