我try 过下面的代码,使用new_callable=PropertyMock来模拟属性调用,使用autospec=True来访问副作用函数中的self:

from unittest.mock import PropertyMock

def some_property_mock(self):
    if self.__some_member == "some_value"
        return "some_different_value"
    else:
        return "some_other_value"

mocker.patch.object(
    SomeClass, "some_property", new_callable=PropertyMock, autospec=True, side_effect=some_property_mock)

它会引发以下异常: ValueError: Cannot use 'autospec' and 'new_callable' together

是否有其他替代方案来实现预期的行为?

编辑: 我try 过这篇文章https://stackoverflow.com/a/77940234/7217960中提供的解决方案,但它似乎不适用于PropertyMock.打印result会显示MyMock name='my_property()' id='136687332325264'而不是预期的2.

from unittest import mock

class MyClass(object):
    def __int__(self):
        self.my_attribute = 10

    @property
    def my_property(self):
        return self.my_attribute + 1
 
def unit_under_test():
    inst = MyClass()
    return inst.my_property
 
class MyMock(mock.PropertyMock):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print("MyMock __init__ called.")
 
with mock.patch.object(mock, 'MagicMock', MyMock):
    with mock.patch.object(MyClass, 'my_property', autospec=True, side_effect=lambda self: 2) as spy:
        result = unit_under_test()
        assert result == 2
        assert spy.call_count == 1

推荐答案

由于属性some_property是用MagicMock修补的,然后用MyMock修补的,并且您想要在调用时设置可调用属性的返回值,因此您应该对用MyMock修补MagicMock返回的模拟对象这样做:

with mock.patch.object(mock, 'MagicMock', MyMock) as property_mock:
    with mock.patch.object(MyClass, 'my_property', autospec=True) as spy:
        property_mock.side_effect = lambda self: 2
        # or property_mock.return_value = 2
        result = unit_under_test()
        assert result == 2
        assert spy.call_count == 1

演示 : https://ideone.com/rKo8mO

Python相关问答推荐

为什么Pydantic在我申报邮箱时说邮箱丢失

两极按组颠倒顺序

流畅的模式,采用Escc方法

从单个列创建多个列并按pandas分组

删除pandas rame时间序列列中未更改的值

使用Beautiful Soup获取第二个srcset属性

在上下文管理器中更改异常类型

在Python和matlab中显示不同 colored颜色 的图像

大Pandas 胚胎中产生组合

删除最后一个pip安装的包

使用索引列表列表对列进行切片并获取行方向的向量长度

Vectorize多个头寸的止盈/止盈回溯测试pythonpandas

在Polars(Python库)中将二进制转换为具有非UTF-8字符的字符串变量

如何在Django基于类的视图中有效地使用UTE和RST HTIP方法?

pyscript中的压痕问题

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

如何在turtle中不使用write()来绘制填充字母(例如OEG)

如何杀死一个进程,我的Python可执行文件以sudo启动?

将标签移动到matplotlib饼图中楔形块的开始处

在pandas/python中计数嵌套类别