簡體   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