In my last post, I showed you how to use setter dependency injection to mock an Apple built-in class by:
- Creating a super simple test double by hand
- Extracting the dependency as an instance variable
- Inject the test double in the Given phase
Two astute readers wrote in about a problem in this example. I’ll describe the problem, a workaround, and two solutions in this post. I’ve also created a sample project called WhereIsMyApple on GitHub. This app has one scene named
List that shows some Apple retail stores in a table view. When the user taps on a row, the app displays the selected retail store in Apple Map.
Here is the
MapViewController in my last post again. I’m showing only the relevant code here.
class MapViewController: UIViewController
var mapItem: MKMapItem!
func displayLocateStore(viewModel: List.LocateStore.ViewModel)
let placemark = MKPlacemark(coordinate: viewModel.coordinate, addressDictionary: viewModel.addressDictionary)
mapItem = MKMapItem(placemark: placemark) // This will overwrite our test double ...
mapItem.name = viewModel.name
displayLocateStore(viewModel:) method extracts the coordinate and address data from the
viewModel argument. It then creates a
MKPlacemark object that is used to instantiate a new
MKMapItem instance. Next, it sets the
name property, and invokes the
openInMaps(launchOptions:) method. The effect is to display the store in the Apple map.
The simplest test double that we can create is as follows:
class MapItemSpy: MKMapItem
var openInMapsCalled = false
override func openInMaps(launchOptions: [String : Any]? = nil) -> Bool
openInMapsCalled = true
MapItemSpy class inherits from
MKMapItem, and overrides the
openInMaps(launchOptions:) method. It sets
openInMapsCalled to true when the method is called.
Continue reading →