具有side_effect和autospec的Python模拟属性

时间:2020-08-13 14:54:41

标签: python unit-testing mocking

在模拟具有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通过。但是我不想用普通方法替换属性。这个想法是根据实例的某些属性返回不同的属性值。

任何提示将不胜感激。

0 个答案:

没有答案
相关问题