2015-05-29 65 views
0

模擬模塊時可以訪問「真實」對象嗎?我正在試圖做的是模仿一些功能,但拋出的「真實」的例外,像這樣:模擬模塊時Python模擬訪問「真實」對象

@mock.patch('my_project.requests') 
def test_foo(self, mock_requests): 

    mock_requests.post = mock.Mock(side_effect=requests.ConnectionError()) 

    thread = CommandThread("command", 3, 2, 0) 
    thread.run() #this is were I exercise requests.post 

    self.assert(thread.was_successful is False) 

裏面我CommandThread我有一個像

try: 
    requests.post(url, data=data) 
except (requests.ConnectionError, requests.Timeout): 
    self.was_successful = False 

然而一查,我的測試失敗,因爲異常沒有被捕獲到try/except塊內部(當我喜歡except Exception:時,它的工作原理) 我想這是因爲我在測試用例中嘲笑了這個「名稱空間」,所以實際上提出了my_project.requests.ConnectionError異常而不是正確的,requests.ConnectionError從原始包裝。 是否有可能訪問/拋出「真實」的異常?

回答

1

這是因爲你的模擬實際上覆蓋了代碼中的整個請求模塊。這裏是你如何調試此:

在代碼中,補充一點:

try: 
    requests.post('', data='') 
except (requests.ConnectionError, requests.Timeout): 
    was_successful = False 
except Exception, err: 
    import pdb 
    pdb.set_trace() 

當你運行測試,你將會進入調試程序,讓您可以看看發生了什麼。如果我們看一下你正在追趕的東西,這就是我們看到:

(Pdb) requests.ConnectionError 
<MagicMock name='requests.ConnectionError' id='4562438992'> 

你實際上是受涼模擬ConnectionError因爲你的模擬補丁出整個請求模塊和你在真正的請求錯誤進行餵養。

@mock.patch('my_project.requests.post') 
def test_foo(self, mock_requests): 
    mock_requests.side_effect = requests.ConnectionError() 
    ... 

您可以通過你的模擬更加具體,只有重寫請求模塊上的post方法解決這個問題