Slide 1

Slide 1 text

Injection de dépendance [en Objective-C] :-] R. Bergoin - 1er mars 2016

Slide 2

Slide 2 text

Dépendance • Rapports qui lient certaines choses, certains êtres, et qui les rendent nécessaires les uns aux autres. 2 https://fr.wiktionary.org/wiki/dépendance

Slide 3

Slide 3 text

Injection • Envoi d’information (requête, code, courant, tension) à une unité de traitement https://fr.wiktionary.org/wiki/injection 3

Slide 4

Slide 4 text

Pourquoi injecter la/les dépendance(s)? • Dépendance explicite => code “plus réutilisable” • Tests, tests, tests, tests, tests, tests, tests… • It’s all about feedback : 4 Kent Beck (@KentBeck) 25/02/15 21:31 if you get your coding feedback loop tight enough, then the time required to press cmd-S to save becomes a bottleneck #reallyContinuousTests

Slide 5

Slide 5 text

Test unitaire • Objectif : vérifier le comportement d’une méthode en particulier, d’une classe (ou d’une instance) • Mise en situation (et nettoyage) : setUp et tearDown • Trois types : • in - out • State • Behavior 5

Slide 6

Slide 6 text

Test unitaire • Bonnes pratiques : • Blocs Given / when / expect • Variable / attribut “sut” (system under test) • nommage : testMethodeAppeleeDansWhen_doitFaireÇa 6

Slide 7

Slide 7 text

Test Driven Development Kent Beck (@KentBeck) 24/02/15 21:40 in tdd, each test is a step forward in the problem space and making it pass is a step forward in the solution space. • Écrire le(s) test(s) avant la méthode testée (sans connaitre cette méthode, uniquement en ayant en tête le service qu’elle doit rendre (in-out)) 7

Slide 8

Slide 8 text

Pourquoi injecter la/les dépendance(s)? • Objectif : valider la sauvegarde d’un document • ViewController dépends de DocumentManager • Créer un “FakeDocumentManager” qui “adopte” l’API du “vrai DocumentManager” • Interroger le FakeDocumentManager pour valider la sauvegarde 8

Slide 9

Slide 9 text

Comment injecter ? • Ajout d’un paramètre à la méthode • Méthode qui retourne la dépendance + héritage/ surcharge • Lors de l’instantiation de l’objet (paramètre du constructeur) • Avec un attribut 9

Slide 10

Slide 10 text

Exemple : avec un attribut 10 @interface DocumentViewController : UIViewController @property (nonatomic, strong) DocumentManager *documentManager; @property (nonatomic, assign) BOOL canBeEdited; @end @implementation DocumentViewController […] @end

Slide 11

Slide 11 text

Exemple : avec un attribut 11 @interface FakeDocumentManager : DocumentManager @property (nonatomic, assign) BOOL saveCalled; @end @implementation FakeDocumentManager - (void)saveDocument:(Document *)document { self.saveCalled = YES; } @end

Slide 12

Slide 12 text

Exemple : avec un attribut 12 - (void)testEditAndSaveChanges_shouldSaveMagasin { // Given FakeDocumentManager *fakeDocumentManager = [[FakeDocumentManager alloc] init]; DocumentViewController *sut = [[DocumentViewController alloc] init]; sut.canBeEdited = YES; sut.editing = YES; sut.documentManager = fakeDocumentManager; // <—— Injection // When [solo showViewControllerInCleanWindow:sut]; BOOL saveTapped = [solo waitForTappableText:@"Enregistrer" andTapIt:YES]; // Expect XCTAssertTrue(saveTapped); XCTAssertTrue(fakeDocumentManager.saveCalled); }

Slide 13

Slide 13 text

Exemple : avec un attribut + OCMockito 13 - (void)testEditAndSaveChanges_shouldSaveMagasin { // Given Document *expectedDocumentToBeSaved = nil; // will fail DocumentManager *fakeDocumentManager = mock([DocumentManager class]); DocumentViewController *sut = [[DocumentViewController alloc] init]; sut.canBeEdited = YES; sut.editing = YES; sut.documentManager = fakeDocumentManager; // <—— Injection // When [solo showViewControllerInCleanWindow:sut]; BOOL saveTapped = [solo waitForTappableText:@"Enregistrer" andTapIt:YES]; // Expect XCTAssertTrue(saveTapped); [verify(fakeDocumentManager) saveDocument:expectedDocumentToBeSaved]; }

Slide 14

Slide 14 text

Limites • Peut faire partie de l’API (publique) de l’objet • Solution : cacher la dépendance dans une extension (ViewController+Dependencies.h) 14

Slide 15

Slide 15 text

Limites (Swift 2) • @Testable import ModuleUnderTest • et tout ce qui est privé, ne l’est plus (classes, méthodes…) 15

Slide 16

Slide 16 text

Questions ? Merci à Jon Reid : http://qualitycoding.org/dependency-injection/