Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Unit Testing for an iOS developer
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
jsa :~
October 11, 2012
Programming
380
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Unit Testing for an iOS developer
1st talk of this series.
jsa :~
October 11, 2012
More Decks by jsa :~
See All by jsa :~
CloudKit First Take
jamessa
0
150
Docker in Golang
jamessa
10
2.1k
Better Design Through Testing
jamessa
3
430
Other Decks in Programming
See All in Programming
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
570
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
2k
React本体のコードリーディング
high_g_engineer
1
160
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
560
AIの中の人になってみる
htkym
0
140
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
220
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
240
Oxlintはいいぞ(続)
yug1224
1
480
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
230
「人を評価する AI」の設計と実装
ryoyanara
0
260
Deep dive into the select statement (GopherCon UK)
jespino
0
150
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Mind Mapping
helmedeiros
PRO
1
340
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Designing for humans not robots
tammielis
254
26k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
630
Designing Experiences People Love
moore
143
24k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
480
Large-scale JavaScript Application Architecture
addyosmani
515
110k
GitHub's CSS Performance
jonrohan
1033
470k
Designing for Timeless Needs
cassininazir
1
460
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
370
Transcript
UNIT TESTING jamie sa @JAMEX for an iOS developer Saturday,
October 20, 12
UNIT TESTING IS NOT FOR IOS Unit Testing is awesome
for guaranteeing consistent behavior of infrastructure. - bbum 2005 Saturday, October 20, 12
@implementation BrowseOverflowViewControllerTests { BrowseOverflowViewController *viewController; UITableView *tableView; id<UITableViewDataSource> dataSource; UINavigationController
*navController; SEL realViewDidAppear, testViewDidAppear; SEL realViewWillDisappear, testViewWillDisappear; SEL realUserDidSelectTopic, testUserDidSelectTopic; BrowseOverflowObjectConfiguration *objectConfiguration; } + (void)swapInstanceMethodsForClass: (Class) cls selector: (SEL) sel1 andSelector: (SEL) sel2 { Method method1 = class_getInstanceMethod(cls, sel1); Method method2 = class_getInstanceMethod(cls, sel2); method_exchangeImplementations(method1, method2); } Method Swizzling Saturday, October 20, 12
@implementation BrowseOverflowViewControllerTests { BrowseOverflowViewController *viewController; UITableView *tableView; id<UITableViewDataSource> dataSource; UINavigationController
*navController; SEL realViewDidAppear, testViewDidAppear; SEL realViewWillDisappear, testViewWillDisappear; SEL realUserDidSelectTopic, testUserDidSelectTopic; BrowseOverflowObjectConfiguration *objectConfiguration; } + (void)swapInstanceMethodsForClass: (Class) cls selector: (SEL) sel1 andSelector: (SEL) sel2 { Method method1 = class_getInstanceMethod(cls, sel1); Method method2 = class_getInstanceMethod(cls, sel2); method_exchangeImplementations(method1, method2); } Method Swizzling in runtime.h OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); Saturday, October 20, 12
UNIT TESTING SLOWS DOWN DEVELOPMENT PROCESS Unit Testing is core
part of ANY Agile best practice. Saturday, October 20, 12
Saturday, October 20, 12
UNIT TESTS ARE A FORM OF SAMPLE CODE Saturday, October
20, 12
- (void)testArticleWithIncompletedAttachmentShouldBeDecorated { NSArray *changedArticleReps = [self loadDataFile:@"PostWithIncompleteAttachmentInformation"]; STAssertNotNil(changedArticleReps, @"should
be a JSON array"); NSArray *touchedArticles = [WAArticle insertOrUpdateObjectsUsingContext:context withRemoteResponse:changedArticleReps usingMapping:nil options:IRManagedObjectOptionIndividualOperations]; WAArticle *article = [touchedArticles objectAtIndex:0]; STAssertEquals((NSUInteger)20, [article.files count], @"attachments should be decorated to 20"); NSFetchRequest *fetchRequest = [[WADataStore defaultStore] newFetchRequestForFilesInArticle:article]; NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:article.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; NSError *fetchError = nil; if (![fetchedResultsController performFetch:&fetchError]) NSLog(@"Error fetching: %@", fetchError); STAssertEquals((NSUInteger)20, [[fetchedResultsController fetchedObjects] count], @"Should be 20."); for (WAFile *photo in [fetchedResultsController fetchedObjects]) { STAssertEqualObjects(@"public.jpeg", photo.resourceType, @"Type must be jpeg."); STAssertEqualObjects(@"image", photo.remoteResourceType, @"Must be an image."); STAssertNotNil(photo.smallThumbnailURL, @"Small thumbnail required"); STAssertNotNil(photo.thumbnailURL, @"Medium thumbnail required"); } Saturday, October 20, 12
USE OCMOCK OCMATCHER Saturday, October 20, 12
USE OCMOCK OCHAMCREST Saturday, October 20, 12
- (void)testOpenConnectionFail { __block BOOL complete = NO; __weak WAWebSocket
*wSocket = webSocket; [[[mockSocket expect] andDo:^(NSInvocation *invocation) { [wSocket performSelector:@selector(webSocket:didFailWithError:) withObject:nil }] open]; [webSocket replaceWebSocketConnection:(SRWebSocket*)mockSocket]; [webSocket openConnectionOnSucces:^{ complete = YES; STFail(@"Websocket connection should fail to be opened."); } onFailure:^(NSError *error) { complete = YES; // success }]; while (complete == NO && [asyncWaitUntil timeIntervalSinceNow] > 0) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:asyncWaitUntil]; } if (complete == NO) { STFail(@"Websocket connection should be opened on time."); } [mockSocket verify]; } Saturday, October 20, 12
IT’S FASTER THAN WRITING CODE WITHOUT TESTS Saturday, October 20,
12
It’s your turn NOW. Saturday, October 20, 12