当两个文件都使用上下文管理器时,我很难弄清楚如何模拟在一个类中打开两个文件。我知道如何使用mock模块对一个上下文管理的文件进行模拟,如下所示:
@patch('__builtin__.open')
def test_interface_mapping(self, mock_config):
m = MagicMock(spec=file)
handle = m.return_value.__enter__.return_value
handle.__iter__.return_value = ('aa', 'bb')
我的问题是,当一个类在同一个调用中打开两个不同的文件时,如何执行此操作。在我的示例中,类__init__()
将文件预加载到两个Map中。该类在其他类中使用。我希望模拟这两个文件的加载以提供测试数据,以便使用IfAddrConfig对象的其他类可以根据我预加载的测试文件内容进行测试。
下面是一个类的例子,我正在努力使用它在__init__()
中加载两个文件,我想模拟这两个文件来加载我的测试注入文件内容。getInterfaceMap()是一个经常被调用的函数,所以我不希望它在每次调用时都加载和解析文件,这就是在__init__()
中预加载一次Map的原因。
class IfAddrConfig(object):
def __init__(self):
# Initialize the static maps once since they require file operations
# that we do not want to be calling every time getInterfaceMap() is used
self.settings_map = self.loadSettings()
self.config_map = self.loadConfig()
def loadConfig(self):
config_map = defaultdict(dict)
with open(os.path.join('some_path.cfg'), 'r') as stream:
for line in stream:
# Parse line and build up config_map entries
return config_map
def loadSettings(self):
settings_map = {}
with open('another_path.cfg', 'r') as stream:
for line in stream:
# Parse line and build up settings_map entries
return settings_map
def getInterfaceMap(self, interface):
# Uses both the settings and config maps to finally create a composite map
# that is returned to called
interface_map = {}
for values in self.config_map.values():
# Accesss self.settings_map and combine/compare entries with
# self.config_map values to build new composite mappings that
# depend on supplied interface value
return interface_map
5条答案
按热度按时间nszi6y051#
您必须使用修补的
open
对象(mock_open
)的side_effect
属性,并且不要忘记为__exit__
方法设置return_value
。**[EDIT]**我发现了一个更优雅的方法在contextlib中使用时模拟内置的“open”函数
所以你可以把测试改写成
从python3.4开始,你也可以使用readline(),readlines(),而不用模仿其他的东西。
vuktfyat2#
如果你需要对文件内容进行更多的控制,你可以使用wrapper函数,它根据文件名替换文件的内容,就像原来的
open
一样。在
elif
链中,为每个现有文件路径设置“文件内容”。试验:
yjghlzjz3#
你需要创建两个'file'模拟,并模拟
open
以在open()
被调用时按顺序返回它们。side_effect
属性允许你这样做:被模拟的
open()
调用在被调用时首先返回handle1
,然后返回handle2
。然后,任一对象使用模拟来响应被调用的__enter__()
,该模拟返回用于__iter__
调用的给定元组。olhwl3o24#
您可以在补丁中使用它来代替
mock_open
...使用
传入文件名的字典:内容,就像这样
v9tzhpje5#
这里有点晚了,但是这里有一个夹具,它将让你以一种更清晰和现代的方式来做这件事,这要归功于更新的python版本上的
mocker
: