Rodrigo Ruiz
Rodrigo Ruiz

Reputation: 4355

How to mock CLLocationManager in Swift

I was not able to override the location property of CLLocationManager. Any ideas on how to do that?

If I do:

class MockCLLocationManager: CLLocationManager {
    var location {
        get {
            return CLLocation(latitude: 0, longitude: 0)
        }
    }
}

I get an error: '@objc' getter for non-'@objc' property

Thank you.

Upvotes: 6

Views: 4891

Answers (2)

Tomáš Kohout
Tomáš Kohout

Reputation: 785

This might be a bit late answer but since I was also looking for the same thing here it is:

You would you use a opposite approach. First declare a protocol you will use in case of actual CLLocationManager

protocol LocationManager{
    var location:CLLocation? {get}
}

And make the CLLocationManager conform to it

extension CLLocationManager:LocationManager{}

This way you can mock the location manager in your tests like this:

class MockLocationManager:LocationManager{
         var location:CLLocation? = CLLocation(latitude: 55.213448, longitude: 20.608194)
}

But can also pass CLLocationManager instead of it in production code.

See more here: https://blog.eliperkins.me/mocks-in-swift-via-protocols/

Edit fixed broken link

Upvotes: 11

Zaster
Zaster

Reputation: 910

this works for me:

fileprivate class MockLocationManager : CLLocationManager {
    var mockLocation: CLLocation?
    override var location: CLLocation? {
        return mockLocation
    }
    override init() {
        super.init()
    }
}

and on the test itself, just assign a clllocation to the mockLocation

let locationManager = MockLocationManager()
locationManager.mockLocation = anyLocation

and test your inner logic like:

yourClass.locationManager(locationManager, didUpdateLocations: [anyLocation])

Upvotes: 2

Related Questions