簡體   English   中英

如何模擬 python 中模塊的導入?

[英]How to mock the import of a module in python?

考慮以下項目結構:

/project
- folder/
    - some_config_module.py
    - func.py
- test/
    - __init__.py
    - test_config.py
    - test.py

假設以下代碼

# func.py
import folder.some_config_module as config

def search_for_data():
    var = config.predefined_parameter
    # rest of code

我現在想為search_for_data編寫一個單元測試。 為了以明智的方式做到這一點,我需要模擬some_config_module的導入,即我的嘗試

# test.py
import unittest
from unittest.mock import patch
import tests.test_config as test_config
from folder.func import serach_for_data


class TestSearchForData(unittest.TestCase):
    @patch('folder.some_config_module')
    def test_one(self, test_config):
        self.assertEqual(search_for_data(), 0)

if __name__ == "__main__":
    unittest.main()

這不會導致預期的行為:我想要的是test_one內的search_for_data導入test.test_config而不是folder.some_config_module 這段代碼基於這個答案......但我似乎誤解了關於mock的一些相當基本的東西......

由於您的 function search_for_data使用在func的全局命名空間中導入的名稱config ,因此您需要覆蓋它而不是覆蓋的folder.some_config_module

@patch('folder.func.config')

import folder.some_config_module as config這樣的導入等效於執行以下操作:

import folder.some_config_module
config = folder.some_config_module
del folder.some_config_module

因此,它將變量config添加到該模塊( func.py )的命名空間中,這就是search_for_data正在使用的內容。 search_for_data的角度來看, config是一個引用模塊的名稱還是引用其他東西都沒有關系,它只知道它需要從全局命名空間加載該名稱(在這種情況下它是模塊func.py )


在運行時search_for_data將在其全局命名空間( search_for_data.__globals__ )中查找config ,模擬修補此全局字典並將此字典中的名稱config臨時替換為模擬 object 並在拆卸期間將其恢復。

import os.path as path
from unittest.mock import patch

def func():
    print(path)


print(f"Before patch: {func.__globals__['path']}")
with patch("__main__.path"):
    print(f"During patch: {func.__globals__['path']}")
    func()

print(f"After patch: {func.__globals__['path']}")

輸出:

Before patch: <module 'posixpath' from '/usr/lib/python3.8/posixpath.py'>
During patch: <MagicMock name='path' id='140233829017776'>
<MagicMock name='path' id='140233829017776'>
After patch: <module 'posixpath' from '/usr/lib/python3.8/posixpath.py'>

暫無
暫無

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

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