CocoaHeads Rennes #10 : Mock Objects

849 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
849
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

CocoaHeads Rennes #10 : Mock Objects

  1. 1. CocoaHeads Rennes #10 Quentin Arnault 10 mai 2012 Mock objects, théorie et application
  2. 2. Ce que vous allez apprendre➡ ce que sont les mock objects,➡ ce qu’ils vous apporteront,➡ les utiliser grâce à OCMock.
  3. 3. Contexte etregard sur la POO Retour d’expérience Photo d’identité et photo de famille Montre moi du code !
  4. 4. Contexte et regard sur la POO
  5. 5. plus faciletests automatisés Contexte ? plus efficace outils meilleure maintenabilité
  6. 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. 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. 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. 9. HTTP ClientWebservice Client Webservice Client Delegate Parser
  10. 10. ... ... ... ... ... HTTP ... Cl. observ. W. Cl. parser ... ... ... ...... ... ... ... ...
  11. 11. ... ... ... ... ... HTTP test ... object Cl. test observ. W. Cl. object test parser ... ... ... object ...... ... ... ... ...
  12. 12. Photo d’identité et photo de famille
  13. 13. objets factices (dummy object)➡ vient remplacer «bêtement» l’objet de production➡ mais pas de comportements
  14. 14. objets bouchon (stub object)➡ vient remplacer un objet de production➡ retourne des valeurs➡ comportement souvent partiel
  15. 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. 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. 17. Montre moi du code !
  18. 18. Une installation simple123
  19. 19. Premiers pasHTTPClient *httpClient = [[HTTPClient alloc] init];WebServiceClient *client = [[WebServiceClient alloc] initWithHTTPClient:httpClient];
  20. 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. 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. 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. 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. 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. 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. 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. 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. 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. 29. Retour d’expérience
  30. 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. 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. 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. 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. 34. Pourquoi les utiliser ?➡ minimisation des interactions➡ minimisation de l’exposition de l’état de l’objet testé➡ tests plus rapide
  35. 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. 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. 37. Écrivez les tests que vous voudriez lire.
  38. 38. julien@cocoaheads.fr CocoaHeads #10 thomas.dupont@cocoaheads.frMock objects, théorie et application Mail : quentin.arnault@gmail.com

×