繁体   English   中英

如何模拟嵌套函数?

[英]How to mock nested functions?

我使用的模拟库是...... mock

当我尝试为函数(遗留代码)编写测试用例时,我遇到了这个“模拟嵌套函数”问题。

此函数使用了非常复杂的嵌套函数,并且对其他模块具有很强的依赖性。

我想知道是否可以使用mock来模拟嵌套函数。

例如,您需要从Google DRIVE API模拟嵌套函数调用(链接函数)

result = get_drive_service().files().insert(body='body', convert=True).execute()   

所以你需要修补函数:service_mock(),files(),insert(),直到last execute()响应:

from mock import patch
with patch('path.to.import.get_drive_service') as service_mock:
   service_mock.return_value.files.return_value.insert.\
   return_value.execute.return_value = {'key': 'value', 'status': 200}

主要方案:第一。 return_value .second。 return_value 。第三。 return_value .last。 return_value = rsp

一个选项是更改您的功能,以便它可选择接受调用的函数,例如,如果您有:

def fn_to_test():
  def inner_fn():
    return 1
  return inner_fn() + 3

将其更改为:

def fn_to_test( inner_fn = null )
  def inner_fn_orig():
    return 1
  if inner_fn==null:
    inner_fn = inner_fn_orig
  return fn() + 3

然后“真实”使用将获得正确的内部功能,并且在您的测试中,您可以提供自己的功能。

fn_to_test() # calls the real inner function
def my_inner_fn():
  return 3
fn_to_test( inner_fn=my_inner_fn ) # calls the new version

你也可以这样做:

def fn_to_test():
  def inner_fn_orign():
    return 1
  inner_fn = inner_fn_orig
  try:
    inner_fn = fn_to_test.inner_fn
  excecpt AttributeError:
    pass
  return inner_fn() + 3

这样你只需定义覆盖:

fn_to_test() # calls the real inner function
def my_inner_fn():
  return 3
fn_to_test.inner_fn = my_inner_fn
fn_to_test() # calls the new version

我看到这样做的唯一方法是动态创建外部函数的副本,使用模拟函数的代码修改函数的代码对象常量:

嵌套函数是否存在等价的覆盖?

您是否尝试使用模拟对象替换嵌套函数? 如果是这样,无论函数多么复杂,这都是相当简单的。 您可以使用MagicMock替换几乎任何python对象。

如果你需要模拟一个返回某个东西的函数,你可以设置MagicMockreturn_value参数。 它看起来像这样:

>>> super_nested_mock = mock.MagicMock()
>>> super_nested_mock.return_value = 42
>>> super_nested_mock()
42

但是,如果您正在尝试测试另一段在内部某处调用super_nested函数的代码,并且想要将其模拟出来,则需要使用补丁 在模拟库中,它看起来像这样:

with patch('super_nested') as super_nested_mock:
    super_nested_mock.return_value = "A good value to test with"
    assert my_function_that_calls_super_nested(5) == 20

这里,通常调用super_nestedwith块中的任何内容都将调用super_nested_mock并返回您为其设置的值。

你需要在补丁程序中调用什么,这有一些微妙之处。 主要是,您希望将对象修补为您正在测试的模块。 有关更多说明,请参阅“ 修补位置 ”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM