---
title: Faking CoreLocation... Inconceivable!
teaser:
tags: testing,ios
author: Matt Mongeau
published_on: 2012-08-03
---

I decided to get more familiar with integration testing iOS applications. In the past I've found trying to do integration testing analogous with climbing the side of a cliff.

![''](http://media.tumblr.com/tumblr_m86zk4MjLy1qd1tqw.jpg)

Given that I'm no Dread Pirate Roberts this has proven very challenging in the past. To challenge myself even further I decided to write an integration test around CoreLocation. In the simulator I can set a location for myself and to some degree I could test with this, but I wanted to be able to have different test scenarios given different locations.

![''](http://media.tumblr.com/tumblr_m872w8UdKe1qd1tqw.png)

One solution was to use something like [FTLocationSimulator](https://github.com/futuretap/FTLocationSimulator) and do the following:

```objectivec
#ifdef FAKE_CORE_LOCATION
    self.locationManager = [[FTLocationSimulator alloc] init];
#else
    self.locationManager = [[CLLocationManager alloc] init];
#endif
```

 But I'm not a big fan of adding conditional flags in my code. Also I don't feel like I have a lot of control over what happens in my code. Instead I prefer doing something closer to dependency injection. Wherever I would normally do `[[CLLocationManager alloc] init]` I instead do `[MyLocationManager sharedInstance]`. MyLocationManager is a singleton which will delegate methods to it's own locationManager. The basic setup looks something like:

```objectivec
#import "MyLocationManager.h"
#import <CoreLocation/CoreLocation.h>

@implementation MyLocationManager
@synthesize locationManager;

static MyLocationManager *sharedSingleton;
+ (id)sharedInstance {
    static BOOL initialized = NO;
    if(!initialized) {
        initialized = YES;
        sharedSingleton = [[MyLocationManager alloc] init];
    }
    return sharedSingleton;
}
- (id) init {
    if (self = [super init]) {
        locationManager = [[CLLocationManager alloc] init];
    }
    return self;
}
@end
```

And my fake location manager:

```objectivec
#import "CLLocationManagerFake.h"
#import <CoreLocation/CoreLocation.h>

@implementation CLLocationManagerFake
@synthesize desiredAccuracy;
@synthesize location;

-(id) init {
    if (self = [super init]) {
        self->location = [[CLLocation alloc] initWithLatitude:0.0 longitude:0.0];
    }
    return self;
}

- (void)startUpdatingLocation {
    [self.delegate locationManager:self didUpdateToLocation:self->location fromLocation:self->location];
}

@end
```

And in my tests I can do the following:

```objectivec
CLLocationManagerFake *fake = [[CLLocationManagerFake alloc] init];
CLLocation *fakeLocation = [[CLLocation alloc] initWithLatitude:42.356426 longitude:-71.061993];
[fake setLocation:fakeLocation];
[[TTimeLocationManager sharedInstance] setLocationManager:fake];
```

Now I have complete control in my tests without polluting my actual code. If I want to use a different fake or have more control over specific scenarios I am able to do so with ease. I can also keep my test dependent code out of my final target.

![''](http://media.tumblr.com/tumblr_m872t6tjA01qd1tqw.jpg)

"HE DIDN'T FALL? INCONCEIVABLE. "
