【发布时间】:2019-12-12 18:58:58
【问题描述】:
我有一个函数 foo 调用另一个函数 get_info_from_tags。
这是get_info_from_tags 的实现:
def get_info_from_tags(*args):
instance_id = get_instance_id()
proc = subprocess.Popen(["aws", "ec2", "describe-tags", "--filters", f"Name=resource-id,Values={instance_id}"],
stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
em_json = json.loads(out.decode('utf8'))
tags = em_json['Tags'] # tags list
results = []
for arg in args:
for tag in tags:
if tag['Key'] == arg:
results.append(tag['Value'])
return results
有一组 10 个可能的 args 可以传递给get_info_from_tags,我需要返回正确的数组(我不想调用 aws 服务,这就是我模拟的重点,我将手动设置字典中的值)。
如何模拟get_info_from_tags,以便在我调用时
get_info_from_tags('key1', 'key2' ...)
在 foo 函数内部,我得到了我想要的结果?
我已经尝试过pytest的一些功能,但似乎不太明白。
一个可能的解决方案是创建另一个函数:
def mocked_get_info_from_tags(*args):
values = []
for arg in args:
values.append(my_dictionary[arg])
return values
但我不知道如何在测试环境中实现此覆盖。
谢谢。
【问题讨论】:
-
鉴于您对
get_info_from_db的实现,我不明白为什么您需要模拟该函数而不是db_connector.get。你能解释一下吗? -
这是因为,为了简单起见,我在这里写了一个我的实际函数的抽象,它做了比这更复杂的事情。但核心思想是一样的。例如,在我的实际函数中,我调用 subprocess 并运行一些命令。仅模拟
db_connector.get会很复杂,因为在调用它之前,它会运行 subprocess 命令。 -
如果你的脚本的某个
MOCK属性设置为True,你可以在真实条件下使用return [db_connector.get(arg) for arg in args]和return[mock_values(arg) for arg in args]。 -
好的,我明白了,不写实际的函数会导致我没想到的答案。我将使用实际功能编辑问题。
-
@TeodoroMendes 我明白了,但是是什么阻止你嘲笑那个功能呢?您只需要为补丁提供模拟版本。您能否更具体地说明实际问题是什么?
标签: python unit-testing mocking pytest