gpt4 book ai didi

具有函数和属性的 Python 模拟类

转载 作者:行者123 更新时间:2023-11-28 22:32:47 26 4
gpt4 key购买 nike

我在用函数和属性修补类时遇到了一些问题。

我正在使用的项目结构如下:

project
|- src
| |- logic
| | |- sub_logic
| | | | __init__.py
| | | | cache.py
| | | | manager.py
| | | __init__.py
|- test
| | test.py

我的缓存文件是这样的

class Cache(object):
def __init__(self, val):
self._val = val

@property
def Val(self):
return self._val

def other_function(self):
return False

管理器文件看起来像这样

from cache import Cache


class Manager(object):
def __init__(self):
self._cache = Cache(20)

def do_something(self):
if self._cache.Val != 20:
raise ValueError(u"Val is not 20")

return True

def do_something_else(self):
if self._cache.other_function():
raise ValueError(u"Something is True")

我尝试进行的测试如下:

from unittest import TestCase
from mock import PropertyMock, patch

from logic.sub_logic.manager import Manager
from logic.sub_logic.cache import Cache


class ManagerTestCase(TestCase):

def test_01_cache(self):
manager = Manager()
self.assertEqual(manager.do_something(), True)

@patch('logic.sub_logic.manager.Cache.Val', new_callable=PropertyMock)
def test_02_cache(self, property_mock):
property_mock.return_value = 20
manager = Manager()
self.assertEqual(manager.do_something(), True)

@patch('logic.sub_logic.manager.Cache', spec=Cache)
def test_03_cache(self, cache_mock):
cache_mock.other_function.return_value = True
manager = Manager()
with self.assertRaises(ValueError):
manager.do_something_else()

@patch('logic.sub_logic.manager.Cache', spec=Cache)
def test_04_cache(self, cache_mock):
cache_mock.other_function.return_value = True
cache_mock.Val = PropertyMock()
cache_mock.Val.return_value = 20

manager = Manager()
with self.assertRaises(ValueError):
manager.do_something_else()
self.assertEqual(manager.do_something(), True)

@patch('logic.sub_logic.manager.Cache.Val', new_callable=PropertyMock)
@patch('logic.sub_logic.manager.Cache', spec=Cache)
def test_05_cache(self, cache_mock, property_mock):
cache_mock.other_function.return_value = True
property_mock.return_value = 20
manager = Manager()
with self.assertRaises(ValueError):
manager.do_something_else()
self.assertEqual(manager.do_something(), True)

@patch('logic.sub_logic.manager.Cache', spec=Cache)
def test_06_cache(self, cache_mock):
cache_mock.other_function.return_value = True
cache_mock.Val = 20

manager = Manager()
with self.assertRaises(ValueError):
manager.do_something_else()
self.assertEqual(manager.do_something(), True)

问题是 test_04_cache 和 test_05_cache 不工作。调试测试时,提供的模拟参数与我预期的一样。但是经理创建了一个 MagicMock,其中属性 Val 不是 PropertyMock,而是 MagicMock。

我在 PyCharm 调试器中检查了 test_06_cache,报告如下:

  • cache_mock.Val = {int}20
  • manager._cache.Val = {MagicMock}<MagicMock name='Cache().Val' id='61044848'>

我错过了什么吗?还是不可能?

最佳答案

当你使用

@patch('logic.sub_logic.manager.Cache', spec=Cache)

生成的模拟是针对的。然后,您的 Manager 通过在 __init__调用那个类来创建一个实例。因此,您应该在 mock_cache()(注意括号)上设置属性和返回值,这是将分配给 manager._cache 的“实例”,而不是“类”mock_cache

请注意,由于管理器不知道缓存正在使用 @property,您可以设置:

mock_cache().Val = 20

关于具有函数和属性的 Python 模拟类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40607839/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com