dimanche 27 décembre 2015

Python - Unit testing mocking a geolocation object within a class

I'm new to testing in python I'm trying to get my head round mocks. Ive a class which gets address latitude and longitude from a geolocation object that i've set previously in the class. I'm trying to mock this geolocation object and its methods to test it. Here is my 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

I've made an attempt at testing the __get_addr_lat_long function which will requires that I mock a geolocation for the 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()

This test results in a failure: AssertionError: Mock name='mock.address' id='140481378030816' != 'test_address'

Any help would be greatly appreciated!

Aucun commentaire:

Enregistrer un commentaire