Your SlideShare is downloading. ×
  • Like
CocoaHeads Rennes #10 : Mock Objects
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

CocoaHeads Rennes #10 : Mock Objects

  • 472 views
Published

Slides de la session des CocoaHeads Rennaise du 10 mai 2012. Session présentée par Quentin Arnault.

Slides de la session des CocoaHeads Rennaise du 10 mai 2012. Session présentée par Quentin Arnault.

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
472
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
10
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. CocoaHeads Rennes #10 Quentin Arnault 10 mai 2012 Mock objects, théorie et application
  • 2. Ce que vous allez apprendre➡ ce que sont les mock objects,➡ ce qu’ils vous apporteront,➡ les utiliser grâce à OCMock.
  • 3. Contexte etregard sur la POO Retour d’expérience Photo d’identité et photo de famille Montre moi du code !
  • 4. Contexte et regard sur la POO
  • 5. plus faciletests automatisés Contexte ? plus efficace outils meilleure maintenabilité
  • 6. 3 niveaux de tests automatisés • unitaire, • intégration, • de bout en bout. unitaire intégration qualité du feeback bout en bout qualité externe qualité interneSteve Freeman, Nat Pryce. Growing Object-oriented software, Guided by tests, p11
  • 7. Back to basics (POO)➡ Responsabilité : obligation d’accomplir une tâche ou de détenir une information➡ Rôle : ensemble de responsabilités liées entre elles➡ Objet : implémentation d’un ou plusieurs rôles➡ Collaboration : interactions d’ objets ou de rôles
  • 8. C’est à dire Webservice Client Responsabilités Collaborateurs➡ construire les requêtes HTTP ➡ client HTTP➡ traiter les erreurs HTTP/svc ➡ parser➡ informer du résultat ➡ observateur
  • 9. HTTP ClientWebservice Client Webservice Client Delegate Parser
  • 10. ... ... ... ... ... HTTP ... Cl. observ. W. Cl. parser ... ... ... ...... ... ... ... ...
  • 11. ... ... ... ... ... HTTP test ... object Cl. test observ. W. Cl. object test parser ... ... ... object ...... ... ... ... ...
  • 12. Photo d’identité et photo de famille
  • 13. objets factices (dummy object)➡ vient remplacer «bêtement» l’objet de production➡ mais pas de comportements
  • 14. objets bouchon (stub object)➡ vient remplacer un objet de production➡ retourne des valeurs➡ comportement souvent partiel
  • 15. objets allégés (fake object)➡ vient remplacer un objet de production➡ contient une implémentation fonctionnelle mais non adaptée à la production
  • 16. mocks objects (mock object)➡ vient remplacer un objet de production➡ peut retourner des valeurs (comme les objets bouchons)➡ contrôle les messages reçus par rapport au contrat prévu➡ Première phase : enregistrement du contrat➡ Deuxième phase : enregistrement des messages pendant l’exécution du cas de test
  • 17. Montre moi du code !
  • 18. Une installation simple123
  • 19. Premiers pasHTTPClient *httpClient = [[HTTPClient alloc] init];WebServiceClient *client = [[WebServiceClient alloc] initWithHTTPClient:httpClient];
  • 20. Premiers pasid mockClient = [OCMockObject mockForClass:[HTTPClient class]];WebServiceClient *client = [[WebServiceClient alloc] initWithHTTPClient:mockClient];[[mockClient expect] prepare]; Enregistrement du contrat[client fetchUsers]; Enregistrement des messages[mockClient verify];
  • 21. expect[[mock expect] aMethod];[[mock expect] aMethodWithParameter:anObject];[[mock expect] aMethodWithParameter:[OCMArg any]];[[mock expect] aMethodWithParameter:[OCMArg anyPointer]];[[mock expect] aMethodWithParameter:[OCMArg isNotEqual:aValue]];[[mock expect] aMethodWithParameter:[OCMArg checkWithSelector:@selector() onObject:anObject]];[[mock expect] aMethodWithParameter:[OCMArg checkWithBlock:^BOOL(id value){}]];
  • 22. verify [mock verify];Test Suite Tests started.Starting TestIsLife/test_missing_call2012-05-10 14:47:49.413 runTests[10490:13303]! Name: NSInternalInconsistencyException! File: Unknown! Line: Unknown! Reason: OCMockObject[HTTPClient]: expected method was not invoked: prepare#0 0x1b9a022 __exceptionPreprocess() (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation)#1 0x1f76cd6 objc_exception_throw() (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/usr/lib/libobjc.A.dylib)#2 0x1b42a48 +[NSException raise:format:arguments:] (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation)#3 0x1b429b9 +[NSException raise:format:] (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/...Blah blah blah
  • 23. stub[[mock stub] aMethod];[[[mock stub] andReturn:aValue] aMethod];[[[mock stub] andThrow:anException] aMethod];[[[mock stub] andPost:aNotification] aMethod];[[[mock stub] andCall:@selector() onObject:anObject] aMethod];[[[mock stub] andDo:^(NSInvocation *){}] aMethod];
  • 24. stub[[[mock stub] andReturn:aValue] aMethod];[[[mock stub] andPost:aNotification] aMethod];[[[[mock stub] andReturn:aValue] andPost:aNotification] aMethod];[[[mock stub] andReturn:aValue] aMethodWithParameter:[OCMArg isNotNil]];[[[mock stub] andThrow:anException] aMethodWithParameter:[OCMArg isNil]];
  • 25. id mockClient = [OCMockObject mockForClass:[HTTPClient class]];➡ permet de préciser les appels de méthodes que l’on attend➡ ne supporte aucun appel en dehors de ceux définis [[mockClient expect] prepare]; [[[mockClient stub] andReturn:@"tournament"] getBaseUrl]; [[[mockClient stub] andReturn:@"HTTPS"] getProtocol]; [[[mockClient stub] setTimeout:10];
  • 26. id mockClient = [OCMockObject niceMockForClass:[HTTPClient class]];➡ permet de préciser les appels de méthodes que l’on attend➡ ignore tous les appels de méthodes non prévus [[mock expect] prepare] [[mock reject] badMethod]
  • 27. id mockClient = [OCMockObject partialMockForObject:httpClient];➡ permet de préciser les appels de méthodes que l’on attend➡ tout en conservant le comportement de l’objet remplacé [[[mock expect] andForwardToRealObject] prepare]
  • 28. id mockObserver = [OCMockObject observerMock];➡ permet d’observer des notifications [notificationCenter addMockObserver:mockObserver name:notificationName object:nil]; [[mockObserver expect] notificationWithName:notificationName object:[OCMArg any]]
  • 29. Retour d’expérience
  • 30. - (void)test_should_initilize_http_client { // arrange id mockClient = [OCMockObject mockForClass:[HTTPClient class]]; [[mockClient stub] setTimeout:[OCMArg any]]; [[mockClient expect] prepare]; WebServiceClient *client = [[WebServiceClient alloc]initWithHTTPClient:mockClient]; // act [client fetchUsers]; // assert [mockClient verify];}
  • 31. @property (nonatomic, readonly) id mockClient;@synthesize mockClient = mockClient_;- (void)test_should_initilize_http_client { // arrange [[self.mockClient expect] prepare]; WebServiceClient *client = [[WebServiceClient alloc]initWithHTTPClient:self.mockClient]; // act [client fetchUsers]; // verify [self.mockClient verify];}- (id)mockClient { if (!mockClient_) mockClient_ = [ OCMockObject mockForClass:[HTTPClient class]]; [[mockClient_ stub] setTimeout:[OCMArg any]]; } return mockClient_;
  • 32. - (void)test_should_initilize_http_client { // arrange [[self.mockClient expect] prepare]; WebServiceClient *client = [[WebServiceClient alloc]initWithHTTPClient:self.mockClient]; // act [client fetchUsers]; // assert [self.mockClient verify];}
  • 33. - (void)test_should_initilize_http_client { // arrange [[self.mockClient expect] prepare]; WebServiceClient *client = [[WebServiceClient alloc]initWithHTTPClient:self.mockClient]; // act [client fetchUsers];}- (void)setUp { [super setUp]; mockClient_ = nil;}- (void)tearDown { [super tearDown]; [self.mockClient verify];}
  • 34. Pourquoi les utiliser ?➡ minimisation des interactions➡ minimisation de l’exposition de l’état de l’objet testé➡ tests plus rapide
  • 35. Ce qu’il m’ont apporté ?➡ différencier les tests d’état des tests de collaboration➡ nouvel angle d’analyse d’un design : l’interaction VS la classification➡ l’importance d’avoir des dépendances explicites
  • 36. Références➡ http://www.cocoaheads.fr➡ Steve Freeman, Nat Pryce. Growing Object-oriented software, Guided by tests➡ http:// www.mockobjects.com➡ http://ocmock.org➡ http://jamesmead.org/talks/2007-07-09-introduction-to-mock- objects-in-ruby-at-lrug/
  • 37. Écrivez les tests que vous voudriez lire.
  • 38. julien@cocoaheads.fr CocoaHeads #10 thomas.dupont@cocoaheads.frMock objects, théorie et application Mail : quentin.arnault@gmail.com