【问题标题】:pytest mock a function call in __init__ of a classpytest 在类的 __init__ 中模拟函数调用
【发布时间】:2021-03-25 11:42:09
【问题描述】:

我有这样的课,

from external_package.module.sub_module import fun

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.z = fun()
        
    def printer(self):
        print(f"X : {self.x}, y : {self.y}, z: {self.z}")

我想为这个类编写一个单元测试并模拟 init 方法中发生的函数调用。

我试过这样打补丁,

from external_package.module import sub_module
    
def test_my_class(mocker):

    mocker.patch.object(sub_module, 'fun', return_value="this is mocked")
    obj = MyClass(10, 20)
    
    assert obj.z == "this is mocked"

但我可以看到调用没有打补丁,并且在 init 方法中发生了函数调用。

如何使用 pytest-mock 或任何其他模拟包修补调用?

【问题讨论】:

    标签: python python-3.x unit-testing


    【解决方案1】:

    您应该使用使用它的路径而不是原始路径或位置来模拟您的函数。在下面的示例中,定义了对象 MyClass 中的 fun 方法将被模拟,返回值将是“this is mocked”。

    from external_package.module import sub_module
    from my_class import MyClass
    
    def test_my_class(mocker):
    
        mocker.patch.object(MyClass.submodule, 'fun', return_value="this is mocked")
        obj = MyClass(10, 20)
        
        assert obj.z == "this is mocked"
    

    查看link 了解如何在 Python 中模拟对象的一些很好的示例。

    【讨论】:

    • 这运行到错误:MyClass 没有名为 fun 的属性。
    • 我忘记在 MyClass 之后添加 sub_module 但已经更新了。很抱歉这个错误。
    【解决方案2】:

    我可以通过稍微更改源代码中的导入语句来解决这个问题,

    from external_package.module import sub_module 
    
    class MyClass:
        def __init__(self, x, y):
            self.x = x
            self.y = y
            self.z = sub_module.fun()
            
        def printer(self):
            print(f"X : {self.x}, y : {self.y}, z: {self.z}")
    

    请注意,我正在导入子模块并从导入的子模块中调用方法。

    现在,在测试中,我像这样使用了pytest-mock 夹具,

    import external_package
        
    def test_my_class(mocker):
    
        method = mocker.patch("external_package.module.sub_module.fun")
        method.return_value = "this is mocked"
    
        obj = MyClass(10, 20)
        
        assert obj.z == "this is mocked"
    

    我不确定为什么这有效,而不是早期的方法。希望有人能解决这个问题。

    【讨论】:

    • 在您的第二个实现中,您非常具体应该模拟什么函数,您定义了在 sub_module 中执行的函数 funexternal_package 内执行时被模拟并且必须返回“这是模拟的”。在您的第一个实现中,您模拟了sub_module,但没有指定应该模拟的位置。
    猜你喜欢
    • 1970-01-01
    • 2012-09-20
    • 2019-11-07
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    相关资源
    最近更新 更多