繁体   English   中英

在 Python 中模拟导入的类

[英]Mocking imported class in Python

我正在尝试模拟一个在导入所述类的模块中调用的类,我想测试该类。

# application.py
from my_module.my_submodule import MyClass

def my_function(var1):
    instance = MyClass()

    instance.some_function(var1)

和我的测试文件

# test_application.py
import mock
import application

def test_my_function():
    with mock.patch('my_module.my_submodule.MyClass') as MockClass:
        application.my_function(var1)

        MockClass.assert_called()        

这给出了一个错误,说MockClass没有被调用。

现在,通过查看这个问题: 为什么 python 模拟补丁不起作用? ,我受到启发将application.py导入更改为此

# application.py
import my_module.my_submodule as mysub

def my_function(var1):
    instance = mysub.MyClass()

    instance.some_function(var1)

也就是说,我不直接导入我想在测试中模拟的类。 现在它起作用了。

我的问题是,如果这按预期工作,或者我以原始方式做错了什么? 如果我想模拟我想测试的模块中使用的类,是否真的有必要总是像这样导入模块?

是的,它按预期工作,但您修补了错误的目标。 尝试修补application.MyClass

application没有在任何地方使用my_module.my_submodule.MyClass ,而是使用MyClass别名。

不,您不必以某种特定方式导入模块即可模拟/修补某些名称。 您需要做的是查看在运行时如何使用该名称,何时需要修补。

如果测试位于与被测试模块不同的模块中,并且在这种情况下被测试的模块application导入名称并直接使用它,就像在from a import MyClass ,然后在测试模块中导入application和 patch application.MyClass 如果application使用import a然后调用a.MyClass()你必须修补application.a.MyClass

因此,您可以根据application模块中的具体命名场景调整补丁目标。 例如,如果您的测试在同一个application模块中,并且该类用作MyClass ,则需要修补__main__.MyClass

然而,以某种方式编写代码确实可以让您在测试时更容易打补丁。 一个很好的例子是当要模拟的实体是函数参数时。 只需使用模拟参数调用该函数即可。

如果您发现修补过于复杂或看起来不可能,请尝试重写应用程序中的代码,使其更“可测试”。

有关作为参考的另一个示例,请参阅修补程序的位置

暂无
暂无

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

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