在模拟具有side_effect的实例属性时需要一些帮助,以便将该实例作为参数传递给side_effect。
import unittest
from unittest.mock import patch, PropertyMock
class Host:
def __init__(self, name):
self.name = name
@property
def api_version(self):
return "2.0"
def fetch_app(self):
if self.api_version == "1.0":
return "app1"
return "app"
def _get_api_version(host: Host):
print("_get_api_version is called")
if host.name == "host-11":
return "1.0"
return "2.0"
class HostMock(unittest.TestCase):
"""
# fails rightly with TypeError: _get_api_version() missing 1 required positional argument: 'host'
def test_fetch_id_A(self):
mock_host = Host("host-99")
with patch("__main__.Host.api_version", new_callable=PropertyMock, side_effect=_get_api_version):
self.assertEqual(mock_host.fetch_app(), "app")
"""
# But this doesn't even call _get_api_version
def test_fetch_id_B(self):
mock_host = Host("host-11")
with patch("__main__.Host.api_version", side_effect=_get_api_version, autospec=True):
self.assertEqual(mock_host.fetch_app(), "app1")
if __name__ == "__main__":
unittest.main()
如果使用api_version
的常规方法,而不是将其设为属性,则test_fetch_id_B
通过。但是我不想用普通方法替换属性。这个想法是根据实例的某些属性返回不同的属性值。
任何提示将不胜感激。