Python - 在 class 中模拟地理位置对象的单元测试

Python - Unit testing mocking a geolocation object within a class

我是 python 中测试的新手 我正在尝试让我的大脑模拟。我有一个 class,它从我之前在 class 中设置的地理定位对象获取地址纬度和经度。我正在尝试模拟这个地理定位对象及其测试方法。这是我的 class:

from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut

class GeolocationFinder():
    def __init__(self):
        self.location_cache = {}
        self.geolocator = Nominatim()
        self.geolocation = None

    def get_location(self, location):
        if location is None:
            return None, None, None
        elif location in self.location_cache:
            # Check cache for location
            self.set_geolocation_from_cache(location)
            address, latitude, longitude = self.get_addr_lat_long
            return address, latitude, longitude
        else:
            # Location not cached so fetch from geolocator
            self.set_geolocation_from_geolocator(location)
            if self.geolocation is not None:
                address, latitude, longitude = self.get_addr_lat_long()
                return address, latitude, longitude
            return 'None', 'None', 'None'

    def set_geolocation_from_cache(self, location):
        self.geolocation = self.location_cache[location]

    def set_geolocation_from_geolocator(self, location):
        try:
            self.geolocation = self.geolocator.geocode(location, timeout=None)
            if self.geolocation is not None:
                self.location_cache[location] = self.geolocation
                return self.geolocation
        except GeocoderTimedOut as e:
            print('error Geolocator timed out')
            self.geolocation = None

    def get_addr_lat_long(self):
        address = self.geolocation.address
        latitude = self.geolocation.latitude
        longitude = self.geolocation.longitude
        self.geolocation = None
        return address, latitude, longitude

我已经尝试测试 __get_addr_lat_long 函数,这将要求我模拟 class 的地理位置:

class GeolocationFinderTests(unittest.TestCase):
    def setUp(self):
        self.test_geolocation_finder = GeolocationFinder()
        attrs = {'address.return_value': 'test_address', 'latitude.return_value': '0000', 'longitude.return_value': '0000'}
        self.mock_geolocation = Mock(**attrs)
        self.test_geolocation_finder.geolocation = self.mock_geolocation

    def test_get_addr_lat_long(self):
        address, lat, long = self.test_geolocation_finder.get_addr_lat_long()

        self.assertEqual(address, 'test_address')

if __name__ == '__main__':
    unittest.main()

此测试失败: 断言错误:模拟名称='mock.address' id='140481378030816' != 'test_address'

如有任何帮助,我们将不胜感激!

return_value 用于可调用对象,例如如果你在模拟一个对象方法。对于对象属性,您只需使用名称,在这种情况下:

attrs = {'address': 'test_address', 'latitude': '0000', 'longitude': '0000'}