修补从模拟类调用的类函数

2024-09-27 23:25:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我为标题的混乱道歉,我不确定有没有更好的方法来描述这个问题。我有一个python库,其结构如下:

library/
  src/
    code/
      __init__.py
      baseclass.py
      helpers.py
      class1.py
    tests/
      __init__.py
      test_library.py

我正在尝试测试中的类中的函数基类.py. 类中的函数基类.py从class1.py返回类对象,如下所示: 基类.py地址:

from class1 import DeviceClass

class LibraryBuilder:
    def __init__(self, user, password):
......

    def get_devices(self):
        devlist = helpers.call_api('api_url', 'post', header, json)
        #Return a list of dictionaries
        for dev in devlist:
            if dev = "DeviceType":
               return DeviceClass(dev, self)

试验_库.py你知道吗

import pytest
from unittest.mock import patch, Mock
from library.baseclass import LibraryBuilder
import library
from library.class1 import DeviceClass

class TestDeviceList(object):
    @pytest.fixture()
    def api_mock(self, caplog):
        self.mock_api_call = patch('library.helpers.call_api', autospec=True)
        self.mock_api = self.mock_api_call.start()
        self.mock_api.return_value.ok = True
        self.library_obj = library.baseclass.LibraryBuilder('sam@mail.com', 'pass')
        yield
        self.mock_api_call.stop()

    @patch.object('baseclass.class1', 'DeviceClass', autospec=True)
    def test_get_devices_all(self, caplog, dev_mock, api_mock):
        self.mock_api.return_value = return_dict
        devs = self.library_object.get_devices()
        dev_mock.assert_called_with(return_dict, self.library_object)

测试失败,因为从未调用“device\u object”。当我调试时,我看到创建的device\u patch对象不是模拟对象,而是实际的DeviceClass对象。你知道吗

我尝试将设备对象路径引用到patch.object('library.baseclass', 'DeviceClass', autospec=True)。我尝试过导入类的变体,因为我相信这与下面的线程有关,但我无法找出哪里出了问题: Why python mock patch doesn't work?

调用api mock可以正常工作。library\u对象根据call\u api mocked return\u值返回实际实例化的类

我只是将代码从一个文件重构到这个配置,测试在此之前已经通过了。你知道我遗漏了什么吗?你知道吗

编辑

我进行了进一步的调试,我相信这与DeviceClassDeviceBaseClass继承有关_类.py看起来像:

class DeviceBaseClass(object):
    def __init__(self, details, manager):
         self.details = {}
..............
class DeviceClass(DeviceBaseClass):
    def __init__(self, details, manager):
        super(DeviceClass, self).__init__(details, manager)

所以现在我得到了信息TypeError: super() argument 1 must be type not MagicMock。我猜既然我在模仿DeviceClass,那么这个被模仿的类将在super()方法中被调用。我已经看到了一些关于这个的其他帖子,但还没有找到解决办法。我是不是漏掉了什么明显的东西,还是完全走错了方向?你知道吗


Tags: 对象pyimportselfapireturnobjectinit
1条回答
网友
1楼 · 发布于 2024-09-27 23:25:40

终于弄明白了,因为我以为是导入模块的位置。我尝试了所有可能的变体,解决方法是确保从调用对象的位置修补对象。我不知道为什么我昨晚没看到这个!!你知道吗

原始的调用补丁是@patch('baseclass.class1', 'DeviceClass', autospec=True),正确的补丁是@patch('baseclass.DeviceClass', autospec=True),如下所示

import pytest
from unittest.mock import patch, Mock
from library.baseclass import LibraryBuilder
import library
from library.class1 import DeviceClass

class TestDeviceList(object):
    @pytest.fixture()
    def api_mock(self, caplog):
        self.mock_api_call = patch('library.helpers.call_api', autospec=True)
        self.mock_api = self.mock_api_call.start()
        self.mock_api.return_value.ok = True
        self.library_obj = library.baseclass.LibraryBuilder('sam@mail.com', 'pass')
        yield
        self.mock_api_call.stop()

    @patch('Library.baseclass.DeviceClass', autospec=True)
    def test_get_devices_all(self, caplog, dev_mock, api_mock):
        self.mock_api.return_value = return_dict
        devs = self.library_object.get_devices()
        dev_mock.assert_called_with(return_dict, self.library_object)

相关问题 更多 >

    热门问题