Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何模拟超类';是否为单元测试创建一个包含模拟对象的属性?_Python_Mocking - Fatal编程技术网

Python 如何模拟超类';是否为单元测试创建一个包含模拟对象的属性?

Python 如何模拟超类';是否为单元测试创建一个包含模拟对象的属性?,python,mocking,Python,Mocking,我正在尝试为类的\uuuu init\uuuu编写单元测试: def __init__(self, buildNum, configFile = "configfile.txt"): super(DevBuild, self).__init__(buildNum, configFile) if configFile == "configfile.txt": self.config.MakeDevBuild() config属性由supe

我正在尝试为类的
\uuuu init\uuuu
编写单元测试:

def __init__(self, buildNum, configFile = "configfile.txt"):
        super(DevBuild, self).__init__(buildNum, configFile)

        if configFile == "configfile.txt":
            self.config.MakeDevBuild()
config属性由super的
\uuu init\uu
设置。我正在使用,我希望config属性是一个模拟对象。然而,我还没有弄明白如何真正做到这一点。以下是我能想到的最好的测试方法:

def test_init(self):
        with patch('DevBuild.super', create=True) as mock_super:
            mock_MakeDevBuild = MagicMock()
            mock_super.return_value.config.MakeDevBuild = mock_MakeDevBuild

            # Test with manual configuration
            self.testBuild = DevBuild("42", "devconfigfile.txt")
            self.assertFalse(mock_MakeDevBuild.called)

            # Test with automated configuration
            self.testBuild = DevBuild("42")
            mock_MakeDevBuild.assert_called_once_with()
但是,这不起作用--我得到一个错误:

Error
Traceback (most recent call last):
  File "/Users/khagler/Projects/BuildClass/BuildClass/test_devBuild.py", line 17, in test_init
    self.testBuild = DevBuild("42")
  File "/Users/khagler/Projects/BuildClass/BuildClass/DevBuild.py", line 39, in __init__
    self.config.MakeDevBuild()
AttributeError: 'DevBuild' object has no attribute 'config'

显然,我没有正确设置config属性,但我不知道应该在哪里设置它。或者就这件事来说,如果我想做的是可能的话。有人能告诉我需要做什么才能使它工作吗?

您不能通过直接设置来模拟
\uuuu init\uuuu
——请参阅

至于您可以做什么,您可以通过将其传递给修补程序来模拟
\uuuu init\uuuu
,如下所示:

mock_makeDevBuild = MagicMock()
def mock_init(self, buildNum, configFile):
    self.config = MagicMock()
    self.config.MakeDevBuild = mock_makeDevBuild

with patch('DevBuild.SuperDevBuild.__init__', new=mock_init):
    DevBuild("42")
    mock_makeDevBuild.assert_called_once_with()
其中
SuperDevBuild
是DevBuild的基类

如果您真的想模拟
super()
,您可以创建一个类,然后手动将
\uuuu init\uuuu
绑定到对象,如

mock_makeDevBuild = MagicMock()
def get_mock_super(tp, obj):
    class mock_super(object):
        @staticmethod
        def __init__(buildNum, configFile):
            obj.config = MagicMock()
            obj.config.MakeDevBuild = mock_makeDevBuild
    return mock_super
with patch('DevBuild.super', create=True, new=get_mock_super):
    DevBuild("42")
    mock_makeDevBuild.assert_called_once_with()

一个观察:
super
的返回值不是一个具有
config
属性的对象,而是一个具有方法
\uuuu init\uuuu
的对象,该方法将在其参数中添加
config
属性。这是整个
\uuuu init\uuu
?如果是,则只有在未传递任何配置文件名的情况下才会添加self.config.MakeDevBuild,这是您在测试中执行的操作。