2013-03-22 78 views
2

我正在爲我有的模塊編寫一些單元測試。我需要修補open,以便在測試模塊內的功能調用open時,使用模擬代替實際的open如何使用Mock從導入的模塊打開'打開'

此代碼的工作,但我認爲這將打破了另一個測試,因爲沒有恢復open其原始值:

class TestCases(unittest.TestCase): 
    def test_something(self): 
     from amodule import bmodule 

     open_mock = mock.MagicMock(spec=open) 
     bmodule.__builtins__['open'] = open_mock 
     read_mock = mock.MagicMock() 
     open_mock.return_value.__enter__.return_value = read_mock 

     self.assertTrue(bmodule.some_function()) 
     self.assertEqual(open_mock.call_args_list, ['filename1', 'filename2']) 

我怎樣才能做到這一點使用mock.patch

回答

3

而不是在__builtins__中修飾open,你可以在bmodule本身修補它。這樣做的好處是隻有bmodule中的函數才能獲得打補丁的開放函數。 您可以在mock documentation中查看更多細節。

所以,你可以通過使用patch.object作爲一個上下文管理器把你的開放版本到位:

from mock import patch 
class TestCases(unittest.TestCase): 
    def test_something(self): 
     from amodule import bmodule 

     open_mock = mock.MagicMock(spec=open) 
     read_mock = mock.MagicMock() 
     open_mock.return_value.__enter__.return_value = read_mock 
     with patch.object(bmodule, 'open', open_mock, create=True): 
      self.assertTrue(bmodule.some_function()) 
     self.assertEqual(open_mock.call_args_list, ['filename1', 'filename2']) 

with語句保證在執行離開與塊補丁將被刪除。需要create=True部分來說服您打算在bmodule名稱空間中創建open綁定的補丁程序 - 這是一種安全措施,可防止人們意外地嘲笑錯誤的名稱,但在您的情況下,這是需要的,因爲在__builtins__想要在bmodule中綁定它。