2013-03-22 71 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中绑定它。