Upload
cocoaheads-tricity
View
176
Download
0
Embed Size (px)
Citation preview
Testable apps in Swift
Andrzej Dąbrowski [email protected] amplituda.io
A client comes…
– Our Beloved Client
“I have a start-up, I need an app, previous team sucked so I’d like you to continue develop the
project”
Great!Let’s look at the code.
1Split code to independent single-purpose services.
(no tests without that, sorry)
2Write couple of tests.
Example service:
BeaconManager
Public API
Why should I make a wrapper around
CLLocationManager?
• seamlessly manages permissions
• smoothens out beacon power fluctuations
• doesn’t require all listeners to duplicate single beacon filtering code and leaving beacon logic
• enable / disable listening
• saves energy (takes care of switching between monitoring/ranging automatically)
• takes care of background ranging (☠☠☠)
• it’s listeners actually don’t have to care about anything, only implement code on beacon events.
BeaconManager uses another services/APIs
• CLLocationManager for permissions and background ranging (updating location)
• Logger (sends critical logs to back-end)
• Data
• SyncManager
• NSNotificationCenter
BeaconManager is critical service to test
Singletons.Hard to test.
Objective-C dynamic runtime allows us easily change implementation of classes /
methods.
OCMock!
Can I do this in Swift?
Hmm…
Let’s readhttp://ocmock.org/swift/
There are smart people around who claim differently:
http://nshipster.com/swift-objc-runtime/
IMVHO, not the best option.
Where is Swift going?
Will there ever be runtime access in Swift?
I have no idea.
But if Swift is about to be super-fast and super-safe,
I wouldn’t count on it.
Why Obj-C runtime is so great in testing?
• Effortless and quick mocks/stubs
• No refactoring needed at all. Just jump into writing tests.
Disadvantages of OCMock way of testing?
• No compile-time protection
• We can forget to stub some important things
• Encourages a bit to write ugly code (inline mocks / stubs) which could create problems with duplication later
• No explicit list of dependencies like in dependency injection
• Still have to write mocks / stubs :(
Alternatives?
Stubbing based on abstraction layer.
Service Locator or DI
How does it work?
Service Locator
Advantages of SL
• compile-time
• quite quick to implement (actually, sharedInstance properties could be overwritten so that they call Service Locator themselves).
• Service protocols are a beautiful way to investigate app architecture without going too deep into implementation details
Disadvantages of SL
• We need to complicate architecture (is that really bad thing?)
• We can forget to stub some libs
• No explicit list of dependencies (like in DI)
• Still have to write our stubs :(
Dependency injection
"Dependency Injection" is a 25-dollar term for a 5-cent concept.
James Shore
"Dependency Injection" is a 25-dollar term for a 5-cent concept.
James Shore
We must initialise services and inject properties when
app starts.
We could use some automation for initialising
services.
Advantages of DI• compile-time
• explicit list of dependencies (nice app architecture guard)
• we won’t forget to stub anything
• service protocols are a beautiful way to investigate app architecture without going too deep into implementation details
Disadvantages of DI
• Quite not-so-fast to implement
• Architecture gets more complicated (like in SL)
• We still need to write stubs
SL vs. DI
• http://www.martinfowler.com/articles/injection.html
• http://bayou.io/draft/In_Defense_of_Service_Locator.html
• rest of the Internet
Are there any libraries for Dependency Injection?
Typhoon
Swinject
Typhoon
December, 2012 1667StarsFirst github commit
Swinject
July, 2015 454StarsFirst github commit
There’s a single disadvantage of all testing
methods.
No lib with stubs.
I’d like to test like this
Why do I have to write mocks/stubs for Apple or
3rd party libs?
Let’s take a look at modern framework like
angular.js
Which iOS frameworks could be easily stubbed not to duplicate code?
Summary• method / class swizzling is probably not what you want
in Swift
• service locator is quickest way to get legacy code tested
• typhoon and swinject are 3rd party libs for Swift testing
• swinject seems to be nice
• unfortunately, there are no libraries which out of the box give developers stubs / mocks for Apple APIs.
Thank you