首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >已从模块导入后的Python patching (使用unittest.mock)函数

已从模块导入后的Python patching (使用unittest.mock)函数
EN

Stack Overflow用户
提问于 2020-07-27 21:45:13
回答 1查看 187关注 0票数 2

假设我有两个文件:

some_module.py

代码语言:javascript
复制
def get_value_1():
    return 1


def print_value_1():
    print(get_value_1())

和主文件main.py

代码语言:javascript
复制
from unittest.mock import patch
import some_module
from some_module import print_value_1, get_value_1


def mocked_value():
    return 2


if __name__ == '__main__':
    print_value_1()  # prints 1
    with patch.object(some_module, 'get_value_1', mocked_value):
        print_value_1()  # prints 2
        print(some_module.get_value_1())  # prints 2
        print(get_value_1())  # prints 1 - DESIRABLE RESULT IS TO PRINT ALSO 2

正如您所看到的,因为我显式地导入了get_value_1函数,所以补丁不能对它起作用。我基本上理解为什么,那是因为它使用了一个引用,并且引用是在主ran之前导入的(通过在每个调用的函数上调用id()来检查它,并查看地址)。我能以某种方式也劫持导入的引用吗?

(只在main.py中打补丁是不够的,我希望在整个项目中都打上补丁,例如在其他一些some_other_module.py中会有:from some_module import get_value_1,当我调用get_value_1()时,它会调用打过补丁的函数并返回值2)

EN

回答 1

Stack Overflow用户

发布于 2020-07-27 23:10:28

如果使用patchpatch.object,则无法修补模块的每个引用。在您的情况下,这将是例如:

代码语言:javascript
复制
if __name__ == '__main__':
    print_value_1()
    with patch.object(some_module, 'get_value_1', mocked_value):
        with patch.object(sys.modules[__name__], 'get_value_1', mocked_value):
            print_value_1()
            print(some_module.get_value_1()) 
            print(get_value_1())

根据应用程序结构的不同,您可以遍历引用要打补丁的函数的所有模块,例如:

代码语言:javascript
复制
def get_modules():
    return (sys.modules[__name__], some_module, some_other_module)

if __name__ == '__main__':
    patches = []
    for module in get_modules():
        p = patch.object(module, 'get_value_1', mocked_value)
        p.start()
        patches.append(p)
        
    print(some_module.get_value_1())
    print(some_other_module.get_value_1())
    print(get_value_1())
    
    [p.stop() for p in patches]

如果事先没有要修补的所有模块,则必须收集需要在运行时修补的所有模块(例如,get_modules变得更加复杂),例如,通过迭代所有加载的模块,找到要按名称修补的函数,并模拟该函数(假设此时所有模块都已加载)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63116720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档