我想修补类属性以返回原始属性的修改版本。
在此示例中,我想修补
Greeter.greeting
以将值“TEST”添加到实际的 greeting
属性返回的内容中:
class Greeter:
def __init__(self, name: str):
self.name = name
@property
def greeting(self):
return f"Hi {self.name}"
我认为这样的事情可能会起作用:
def test_greeter():
with patch.object(
Greeter, "greeting", new_callable=PropertyMock(wraps=lambda self: f"TEST {self.greeting}")
):
greeter = Greeter(name="Some Person")
assert greeter.greeting == "TEST Hi Some Person"
但这给了我:
TypeError: test_greeter.<locals>.<lambda>() missing 1 required positional argument: 'self'
我也尝试过各种配方,例如:
patch.object(Greeter, "greeting", wraps=lambda self: f"TEST {self.greeting}")
patch.object(Greeter, "greeting", side_effect=lambda self: f"TEST {self.greeting}")
但我运气不好。
这可能吗? 感觉应该如此。
您可以只修补一个替换描述符,如下所示:
from unittest.mock import patch
class Greeter:
def __init__(self, name: str):
self.name = name
@property
def greeting(self):
return f"Hi {self.name}"
def test_greeter():
class FakeGreeting:
def __get__(self, obj, objtype=None):
return f"TEST Hi {obj.name}"
with patch.object(Greeter, "greeting", new=FakeGreeting()):
greeter = Greeter(name="Some Person")
assert greeter.greeting == "TEST Hi Some Person"
以上测试运行成功:
============================ test session starts ============================
platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/lars/tmp/python
collected 1 item
test_property.py::test_greeter PASSED [100%]
============================= 1 passed in 0.02s =============================
我认为
PropertyMock
仅对静态返回值有用;对于您正在做的事情,您需要属性描述符才能访问它所附加的对象。