簡體   English   中英

如何模擬從不同模塊導入的方法中導入的函數

[英]How to mock a function, that is imported within an imported method from different module

我得到了以下功能來測試:

my_package.db_engine.db_functions.py:

from ..utils import execute_cmd
from my_package.db_engine.db_functions import dbinfo 

def dbinfo(db_name):
    params = (cmd_cfg.DB, add_pj_suffix(db_name))
    cmd = get_db_cmd_string(cmd_cfg.DBINFO, params=params)
    cmd_result = execute_cmd(cmd)
    result_dict = map_cmd_output_to_dict(cmd_result)
    return result_dict

此函數獲取數據庫的名稱,然后從中構建一個命令字符串,並使用execute_cmd方法將該命令作為subprocess execute_cmd執行。 我想在不實際執行subprocess情況下測試這個函數。 我只想檢查命令是否正確構建並正確傳遞給execute_cmd 因此,我需要模擬從模塊utils導入的execute_cmd方法。

我的文件夾結構如下:

my_project
|_src
| |_my_package
| | |_db_engine
| | | |_db_functions.py
| | | |_ __init__.py
| | |_utils.py
| | |_ __init__.py
| | |_ ....
| |_ __init__.py
|_tests
  |_test_db_engine.py

所以對於我的測試,我在test_db_engine.py嘗試了以下test_db_engine.py

import unittest
from mock import patch

from my_pacakge.db_engine.db_functions import dbinfo


def execute_db_info_cmd_mock():
    return {
            'Last Checkpoint': '1.7',
            'Last Checkpoint Date': 'May 20, 2015 10:07:41 AM'
    }


class DBEngineTestSuite(unittest.TestCase):
    """ Tests für DB Engine"""

    @patch('my_package.utils.execute_cmd')
    def test_dbinfo(self, test_patch):
        test_patch.return_value = execute_db_info_cmd_mock()
        db_info = dbinfo('MyDBNameHere')
        self.assertEqual(sandbox_info['Last Checkpoint'], '1.7')

實際命令的執行為Last Checkpoint產生1.6 因此,為了驗證是否使用了模擬返回值,我將其設置為1.7 但是沒有使用該函數的模擬,因為測試用例的執行仍然產生1.6因為它正在執行應該用模擬修補的實際函數。

知道我在這里做錯了什么嗎?

您正在修補錯誤的位置。 何處修補部分

patch()通過(臨時)將名稱指向的對象更改為另一個對象。 可以有許多名稱指向任何單個對象,因此要使修補工作,您必須確保修補被測系統使用的名稱。

基本原則是在查找對象的位置打補丁,該位置不一定與定義它的位置相同。

您的被測代碼在他們自己的模塊中發現execute_cmd作為一個全局execute_cmd ,但您沒有修補該引用:

from ..utils import execute_cmd

my_package.utils.execute_cmd引用已修補,但my_package.db_engine.db_functions中的execute_cmd引用仍將指向未修補的原始函數。

改為修補導入的全局:

@patch('my_package.db_engine.db_functions.execute_cmd')

現在dbinfoexecute_cmd查找將使用修補后的模擬對象,而不是from ... import ...語句的原始全局綁定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM