python - 在 Python 中模拟导入的类

标签 python testing

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

# 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 没有被调用。

现在,通过查看这个问题:Why python mock patch doesn't work? ,我受到启发将 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 并修补 application.MyClass。如果 application 使用 import a 然后调用 a.MyClass() 你必须修补 application.a.MyClass.

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

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

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

有关另一个示例作为引用,请参阅 Where to patch

关于python - 在 Python 中模拟导入的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53433214/

相关文章:

multithreading - 可视化多线程 C++ 应用程序调用图、多线程代码覆盖率的工具?

Python猜谜游戏,用字母替换空格并存储在列表中

PHP 5 : return by ref method produces unexpected results

Python模块函数在线程中立即返回

python - 在输出中打印 Python 版本

unit-testing - 如何在 Go 中模拟包方法?

testing - react enzyme 测试,无法读取未定义的属性 'have'

ruby 运动 : Removing a Ruby Class Completely from Object Space

python - 从 Redis 获取数据(异步、串行版本与多处理)

python - 在 matplotlib 3d 中旋转 STL 文件