Python pytest模拟类的_init__中的函数调用

Python pytest模拟类的_init__中的函数调用,python,python-3.x,unit-testing,Python,Python 3.x,Unit Testing,我有一节这样的课 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:

我有一节这样的课

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}")
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"
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"
我想为这个类编写一个单元测试,并模拟在init方法中发生的函数调用

我试过这样修补

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}")
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"
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"
但是我可以看到调用没有被修补,函数调用发生在init方法中


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

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


查看下面的示例,了解如何在Python中模拟对象。

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

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}")
注意,我正在导入子模块并从导入的子模块调用方法

现在,在测试中,我使用了像这样的
pytestmock
夹具

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}")
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"
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"

我不知道为什么这是有效的,而不是早期的方法。希望有人能澄清这一点。

这是一个错误:MyClass没有名为fun的属性。我忘了在MyClass之后添加sub_模块,但已经更新了它。很抱歉出现错误。在第二个实现中,您非常具体地说明了应该模拟的函数,您定义了当在
外部\u包内执行时,来自
子\u模块的
fun
函数将被模拟,并且必须返回“this is mocked”。在第一个实现中,您模拟了
子模块
,但没有指定模拟的位置。