Conf soat tests_unitaires_Mockito_jUnit_170113

195
01/26/13 Test unitaire ? Mock ? TDD ? Kezako ? 1

description

Vous subissez les régressions à chaque livraison ? Vous ne voyez pas l’intérêt des tests unitaires car ils ne servent qu’à tester des additions ? Si c’est le cas, suivez David dans la quête du Test Driven Development. Nous rencontrerons pléthore d'ennemies contre lesquels nous aurons à combattre : bugs, complexité, code statique, couplage fort. Ils essaieront de nous barrer la route, mais heureusement, nous pourrons compter sur nos alliés jUnit, Mockito, refactoring et injection/dépendance

Transcript of Conf soat tests_unitaires_Mockito_jUnit_170113

Page 2: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 3: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 4: Conf soat tests_unitaires_Mockito_jUnit_170113

Nouveau client !

Page 5: Conf soat tests_unitaires_Mockito_jUnit_170113

Nouveau projet !

Page 6: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 7: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 9: Conf soat tests_unitaires_Mockito_jUnit_170113

La documentation explique le code /** * * @param xml : document xml représentant le swap * @return objet Swap */ public Swap parse(String xml) { Swap swap = new Swap(); String currency = getNodeValue("/swap/currency", xml); swap.setCurrency(currency); /* beaucoup de code... */ Date d = new Date(); if(test == 1) { if(d.after(spotDate)) { swap.setType("IRS"); } else { swap.setType("CURVE"); } } else if (test == 2) { if(d.after(spotDate)) { swap.setType("IRS"); } else { swap.setType("CURVE"); } } /* encore beaucoup de code... */ return swap; }

Page 10: Conf soat tests_unitaires_Mockito_jUnit_170113

La documentation explique le code 1 /** 2 * 3 * @param xml : document xml représentant le swap 4 * @return objet Swap 5 */ 6 public Swap parse(String xml) { 7 Swap swap = new Swap(); 8 String currency = getNodeValue("/swap/currency", xml); 9 swap.setCurrency(currency);[...] /* beaucoup de code... */ 530 Date d = new Date(); 531 if(test == 1) { 532 if(d.after(spotDate)) { 533 swap.setType("IRS"); 534 } else { 535 swap.setType("CURVE"); 536 } 537 } else if (test == 2) { 538 if(d.after(spotDate)) { 539 swap.setType("IRS"); 540 } else { 541 swap.setType("CURVE"); 542 } 543 }[...] /* encore beaucoup de code... */1135 return swap;1136 }

1000 LIGNES !

Page 11: Conf soat tests_unitaires_Mockito_jUnit_170113

La documentation a raison

1 /**2 * Always returns true.3 */4 public boolean isAvailable() {5 return false;6 }

Page 12: Conf soat tests_unitaires_Mockito_jUnit_170113

La documentation a raison

1 /**2 * Always returns true.3 */4 public boolean isAvailable() {5 return false;6 }

WTF ?!?

Page 13: Conf soat tests_unitaires_Mockito_jUnit_170113

La documentation n’est plusfiableune aideutile

Page 14: Conf soat tests_unitaires_Mockito_jUnit_170113

4 obj = networkService.getObject("product", id);

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

Faire du code qui marche

Page 15: Conf soat tests_unitaires_Mockito_jUnit_170113

4 obj = networkService.getObject("product", id);

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

Faire du code qui marche

Page 16: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

2 Object obj = null; 5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }

Faire du code qui marche

NullPointerException !

Page 17: Conf soat tests_unitaires_Mockito_jUnit_170113

4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();

1 public void affiche(BankAccount account, ProductService service) {2 System.out.println("Bank Account : "+this.name);3 System.out.println("Autres informations : ");4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();6 System.out.println(account);7 System.out.println("=== FIN ===");8 9 }

Code simple

HTTP://EN.WIKIPEDIA.ORG/WIKI/FILE:JEU_DE_MIKADO.JPG

Page 18: Conf soat tests_unitaires_Mockito_jUnit_170113

4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();

1 public void affiche(BankAccount account, ProductService service) {2 System.out.println("Bank Account : "+this.name);3 System.out.println("Autres informations : ");4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();6 System.out.println(account);7 System.out.println("=== FIN ===");8 9 }

Code simple

HTTP://EN.WIKIPEDIA.ORG/WIKI/FILE:JEU_DE_MIKADO.JPG

Page 19: Conf soat tests_unitaires_Mockito_jUnit_170113

4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();

1 public void affiche(BankAccount account, ProductService service) {2 System.out.println("Bank Account : "+this.name);3 System.out.println("Autres informations : ");4 account = (BankAccount) service.getProduct(this.name);5 account.deposit();6 System.out.println(account);7 System.out.println("=== FIN ===");8 9 }

Code simple

HTTP://EN.WIKIPEDIA.ORG/WIKI/FILE:JEU_DE_MIKADO.JPG

Page 20: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 21: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 22: Conf soat tests_unitaires_Mockito_jUnit_170113

C’est compliqué de fairesimpleun testune évolution

Page 23: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 24: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 25: Conf soat tests_unitaires_Mockito_jUnit_170113

Bonne nouvelle !

Page 26: Conf soat tests_unitaires_Mockito_jUnit_170113

Je vous prend dans mon équipe !

Page 27: Conf soat tests_unitaires_Mockito_jUnit_170113

HTTP://WWW.SXC.HU/PROFILE/HOTBLACK

COMMENT VA T’ON POUVOIR S’EN SORTIR ?

Page 29: Conf soat tests_unitaires_Mockito_jUnit_170113

PRINCIPE DE BASE

Page 30: Conf soat tests_unitaires_Mockito_jUnit_170113

Ecriture du test

Page 31: Conf soat tests_unitaires_Mockito_jUnit_170113

Lancementdu test

Ecriture du test

Page 32: Conf soat tests_unitaires_Mockito_jUnit_170113

Lancementdu test

Correction de l’implémentation

Ecriture du test

KO

Page 33: Conf soat tests_unitaires_Mockito_jUnit_170113

Lancementdu test

Correction de l’implémentation

Ecriture du test

Fin

KO

OK

Page 34: Conf soat tests_unitaires_Mockito_jUnit_170113

Lancementdu test

Correction de l’implémentation

Ecriture du test

Fin

KO

OK

REFACTOR

Page 35: Conf soat tests_unitaires_Mockito_jUnit_170113

Toujours faire le test cassant avant le test passant(pour tester le test)

Page 36: Conf soat tests_unitaires_Mockito_jUnit_170113

TEST UNITAIREtester la plus petite unité de code possible

Page 37: Conf soat tests_unitaires_Mockito_jUnit_170113

TEST UNITAIREtester la plus petite unité de code possible

SIMPLE

Page 38: Conf soat tests_unitaires_Mockito_jUnit_170113

TEST UNITAIREtester la plus petite unité de code possible

SIMPLEFEEDBACK

Page 39: Conf soat tests_unitaires_Mockito_jUnit_170113

TEST UNITAIREtester la plus petite unité de code possible

SIMPLEFEEDBACKCOÛT

Page 40: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 41: Conf soat tests_unitaires_Mockito_jUnit_170113

$400 MILLIONS

Page 42: Conf soat tests_unitaires_Mockito_jUnit_170113

EXEMPLE

Page 43: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_deposit() {3 bankAccount.setBalance(50);4 5 boolean result = bankAccount.deposit(1000);6 7 assertTrue(result);8 assertEquals(1050, bankAccount.getBalance());9 }

3 bankAccount.setBalance(50);

Test d’abord !

Page 44: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_deposit() {3 bankAccount.setBalance(50);4 5 boolean result = bankAccount.deposit(1000);6 7 assertTrue(result);8 assertEquals(1050, bankAccount.getBalance());9 }

3 bankAccount.setBalance(50);

Test d’abord !

Page 45: Conf soat tests_unitaires_Mockito_jUnit_170113

5 boolean result = bankAccount.deposit(1000);

1 @Test2 public void can_deposit() {3 bankAccount.setBalance(50);4 5 boolean result = bankAccount.deposit(1000);6 7 assertTrue(result);8 assertEquals(1050, bankAccount.getBalance());9 }

Test d’abord !

Page 46: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_deposit() {3 bankAccount.setBalance(50);4 5 boolean result = bankAccount.deposit(1000);6 7 assertTrue(result);8 assertEquals(1050, bankAccount.getBalance());9 }

Test d’abord !

7 assertTrue(result);8 assertEquals(1050, bankAccount.getBalance());

Page 47: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 return false;3 }

Page 48: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 return false;3 }

Page 49: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 bal = bal + amount;3 return true;4 }

Page 50: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 bal = bal + amount;3 return true;4 }

Page 51: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

Page 52: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

3 bankAccount.setBalance(100);

Page 53: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

5 boolean result = bankAccount.deposit(-20);

Page 54: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());

Page 55: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 bal = bal + amount;3 return true;4 }

Page 56: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 bal = bal + amount;3 return true;4 }

Page 57: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 if(amount < 0) {3 return false;4 }5 bal = bal + amount;6 return true;7 }

Page 58: Conf soat tests_unitaires_Mockito_jUnit_170113

Test d’abord !

1 boolean deposit(int amount) {2 if(amount < 0) {3 return false;4 }5 bal = bal + amount;6 return true;7 }

Page 59: Conf soat tests_unitaires_Mockito_jUnit_170113

Acteur / Action / Assertion

Page 60: Conf soat tests_unitaires_Mockito_jUnit_170113

les «3 A» : Acteur/Action/Assertion

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

Page 61: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

les «3 A» : Acteur/Action/Assertion

3 bankAccount.setBalance(100);

Acteur

Page 62: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

les «3 A» : Acteur/Action/Assertion

5 boolean result = bankAccount.deposit(-20);

Action

Page 63: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void cant_deposit_with_negative_amount() {3 bankAccount.setBalance(100);4 5 boolean result = bankAccount.deposit(-20);6 7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());9 }

les «3 A» : Acteur/Action/Assertion

7 assertFalse(result);8 assertEquals(100, bankAccount.getBalance());

Assertions

Page 64: Conf soat tests_unitaires_Mockito_jUnit_170113

KISS

Page 65: Conf soat tests_unitaires_Mockito_jUnit_170113

KISSKEEP IT SIMPLE (AND STUPID)

Page 66: Conf soat tests_unitaires_Mockito_jUnit_170113

KISSKEEP IT SIMPLE (AND STUPID)

Page 67: Conf soat tests_unitaires_Mockito_jUnit_170113

7 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99"); 8 9 // Vérifier.10 Assert.assertNotNull("Extra non trouvé.", targetDTO);11 Assert.assertEquals("Les accountId doivent être identiques.",12 "ABC99", targetDTO.getAccountId());

1 @Test 2 public void testGetCustomerOK() { 3 4 LOGGER.info("======= testGetCustomerOK starting..."); 5 6 try { 7 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99"); 8 9 // Vérifier.10 Assert.assertNotNull("Extra non trouvé.", targetDTO);11 Assert.assertEquals("Les accountId doivent être identiques.",12 "ABC99", targetDTO.getAccountId());13 14 } catch (CustomerBusinessException exception) {15 LOGGER.error("CustomerBusinessException : {}",16 exception.getCause());17 Assert.fail(exception.getMessage());18 } catch (UnavailableResourceException exception) {19 LOGGER.error("UnavailableResourceException : {}",20 exception.getMessage());21 Assert.fail(exception.getMessage());22 } catch (UnexpectedException exception) {23 LOGGER.error("UnexpectedException : {}" +24 exception.getMessage());25 Assert.fail(exception.getMessage());26 } catch (Exception exception) {27 LOGGER.error("CRASH : " + exception.getMessage());28 Assert.fail(exception.getMessage());29 }30 31 LOGGER.info("======= testGetCustomerOK done.");32 }

Page 68: Conf soat tests_unitaires_Mockito_jUnit_170113

7 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99"); 8 9 // Vérifier.10 Assert.assertNotNull("Extra non trouvé.", targetDTO);11 Assert.assertEquals("Les accountId doivent être identiques.",12 "ABC99", targetDTO.getAccountId());

1 @Test 2 public void testGetCustomerOK() { 3 4 LOGGER.info("======= testGetCustomerOK starting..."); 5 6 try { 7 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99"); 8 9 // Vérifier.10 Assert.assertNotNull("Extra non trouvé.", targetDTO);11 Assert.assertEquals("Les accountId doivent être identiques.",12 "ABC99", targetDTO.getAccountId());13 14 } catch (CustomerBusinessException exception) {15 LOGGER.error("CustomerBusinessException : {}",16 exception.getCause());17 Assert.fail(exception.getMessage());18 } catch (UnavailableResourceException exception) {19 LOGGER.error("UnavailableResourceException : {}",20 exception.getMessage());21 Assert.fail(exception.getMessage());22 } catch (UnexpectedException exception) {23 LOGGER.error("UnexpectedException : {}" +24 exception.getMessage());25 Assert.fail(exception.getMessage());26 } catch (Exception exception) {27 LOGGER.error("CRASH : " + exception.getMessage());28 Assert.fail(exception.getMessage());29 }30 31 LOGGER.info("======= testGetCustomerOK done.");32 }

Page 69: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test 2 public void testGetCustomerOK() { 3 4 LOGGER.info("======= testGetCustomerOK starting..."); 5 6 try { 7 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99"); 8 9 // Vérifier.10 Assert.assertNotNull("Extra non trouvé.", targetDTO);11 Assert.assertEquals("Les accountId doivent être identiques.",12 "ABC99", targetDTO.getAccountId());13 14 } catch (CustomerBusinessException exception) {15 LOGGER.error("CustomerBusinessException : {}",16 exception.getCause());17 Assert.fail(exception.getMessage());18 } catch (UnavailableResourceException exception) {19 LOGGER.error("UnavailableResourceException : {}",20 exception.getMessage());21 Assert.fail(exception.getMessage());22 } catch (UnexpectedException exception) {23 LOGGER.error("UnexpectedException : {}" +24 exception.getMessage());25 Assert.fail(exception.getMessage());26 } catch (Exception exception) {27 LOGGER.error("CRASH : " + exception.getMessage());28 Assert.fail(exception.getMessage());29 }30 31 LOGGER.info("======= testGetCustomerOK done.");32 }

14 } catch (CustomerBusinessException exception) {15 LOGGER.error("CustomerBusinessException : {}",16 exception.getCause());17 Assert.fail(exception.getMessage());18 } catch (UnavailableResourceException exception) {19 LOGGER.error("UnavailableResourceException : {}",20 exception.getMessage());21 Assert.fail(exception.getMessage());22 } catch (UnexpectedException exception) {23 LOGGER.error("UnexpectedException : {}" +24 exception.getMessage());25 Assert.fail(exception.getMessage());26 } catch (Exception exception) {27 LOGGER.error("CRASH : " + exception.getMessage());28 Assert.fail(exception.getMessage());29 }30 31 LOGGER.info("======= testGetCustomerOK done.");

BRUIT

Page 70: Conf soat tests_unitaires_Mockito_jUnit_170113

KISS !

1 @Test2 public void can_get_customer() throws Exception {3 CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99");4 Assert.assertEquals("Les accountId doivent être identiques.",5 "ABC99", targetDTO.getAccountId());6 }

Page 72: Conf soat tests_unitaires_Mockito_jUnit_170113

VENIR ARMÉ

Page 73: Conf soat tests_unitaires_Mockito_jUnit_170113

JUNIT + MOCKITO + FEST-ASSERT

Page 74: Conf soat tests_unitaires_Mockito_jUnit_170113

JUNIT + MOCKITO + FEST-ASSERT

Page 75: Conf soat tests_unitaires_Mockito_jUnit_170113

Mock ?

simulacre

se fait passer pour ce qu’il n’est pas

comportement paramétrable

Page 76: Conf soat tests_unitaires_Mockito_jUnit_170113

MOCKITO

Page 77: Conf soat tests_unitaires_Mockito_jUnit_170113

doReturn(new BankAccount()).when(daoService).getObject("product", "id");

Page 78: Conf soat tests_unitaires_Mockito_jUnit_170113

doReturn(new BankAccount()).when(daoService).getObject("product", "id");doReturn(new BankAccount())

Page 79: Conf soat tests_unitaires_Mockito_jUnit_170113

doReturn(new BankAccount()).when(daoService).getObject("product", "id");when(daoService)

Page 80: Conf soat tests_unitaires_Mockito_jUnit_170113

doReturn(new BankAccount()).when(daoService).getObject("product", "id"); getObject("product", "id");

Page 81: Conf soat tests_unitaires_Mockito_jUnit_170113

doThrow(IOException.class).when(daoService).getObject("product", "id");

Page 82: Conf soat tests_unitaires_Mockito_jUnit_170113

doThrow(IOException.class).when(daoService).getObject("product", "id");doThrow(IOException.class)

Page 83: Conf soat tests_unitaires_Mockito_jUnit_170113

doThrow(IOException.class).when(daoService).getObject("product", "id");when(daoService)

Page 84: Conf soat tests_unitaires_Mockito_jUnit_170113

doThrow(IOException.class).when(daoService).getObject("product", "id");getObject("product", "id");

Page 85: Conf soat tests_unitaires_Mockito_jUnit_170113

FEST-ASSERT

Page 86: Conf soat tests_unitaires_Mockito_jUnit_170113

assertThat(age).isGreaterThan(5);

Page 87: Conf soat tests_unitaires_Mockito_jUnit_170113

assertThat(myList).containsExactly("MONAD42", "META18")

Page 88: Conf soat tests_unitaires_Mockito_jUnit_170113

NOUVEAU CODE = NOUVEAU TEST

Page 89: Conf soat tests_unitaires_Mockito_jUnit_170113

NOUVEAU BUG = NOUVEAU TEST

Page 90: Conf soat tests_unitaires_Mockito_jUnit_170113

nouveau bug = nouveau test

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

Page 91: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

nouveau bug = nouveau test

6 System.err.println("Error with obj : " + obj.toString());

LE BUG EST ICI !

Page 92: Conf soat tests_unitaires_Mockito_jUnit_170113

nouveau bug = nouveau test

1 @Test2 public void can_return_null_when_ioexception() throws IOException {3 Mockito.doThrow(IOException.class)4 .when(daoService).getObject("product", "azerty");5 6 Object product = service.getProduct("azerty");7 8 assertThat(product).isNull();9 }

Page 93: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_return_null_when_ioexception() throws IOException {3 Mockito.doThrow(IOException.class)4 .when(daoService).getObject("product", "azerty");5 6 Object product = service.getProduct("azerty");7 8 assertThat(product).isNull();9 }

nouveau bug = nouveau test

3 Mockito.doThrow(IOException.class)4 .when(daoService).getObject("product", "azerty");

Page 94: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_return_null_when_ioexception() throws IOException {3 Mockito.doThrow(IOException.class)4 .when(daoService).getObject("product", "azerty");5 6 Object product = service.getProduct("azerty");7 8 assertThat(product).isNull();9 }

nouveau bug = nouveau test

6 Object product = service.getProduct("azerty");

Page 95: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test2 public void can_return_null_when_ioexception() throws IOException {3 Mockito.doThrow(IOException.class)4 .when(daoService).getObject("product", "azerty");5 6 Object product = service.getProduct("azerty");7 8 assertThat(product).isNull();9 }

nouveau bug = nouveau test

8 assertThat(product).isNull();

Page 96: Conf soat tests_unitaires_Mockito_jUnit_170113

nouveau bug = nouveau test

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

Page 97: Conf soat tests_unitaires_Mockito_jUnit_170113

nouveau bug = nouveau test

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

Page 98: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj : " + obj.toString());7 }8 return obj;9 }

nouveau bug = nouveau test

6 System.err.println("Error with obj : " + obj.toString());

LE BUG EST TOUJOURS ICI !

Page 99: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj with id: " + id);7 }8 return obj;9 }

nouveau bug = nouveau test

6 System.err.println("Error with obj with id: " + id);

Page 100: Conf soat tests_unitaires_Mockito_jUnit_170113

nouveau bug = nouveau test

1 public Object getProduct(String id) {2 Object obj = null;3 try {4 obj = networkService.getObject("product", id);5 } catch (IOException e) {6 System.err.println("Error with obj with id: " + id);7 }8 return obj;9 }

6 System.err.println("Error with obj with id: " + id);

Page 101: Conf soat tests_unitaires_Mockito_jUnit_170113

Laissez votre câble tranquille

Page 102: Conf soat tests_unitaires_Mockito_jUnit_170113

TESTER DOIT ÊTRE SIMPLE

Page 103: Conf soat tests_unitaires_Mockito_jUnit_170113

code complexe 1 /** 2 * 3 * @param xml : document xml représentant le swap 4 * @return objet Swap 5 */ 6 public Swap parse(String xml) { 7 Swap swap = new Swap(); 8 String currency = getNodeValue("/swap/currency", xml); 9 swap.setCurrency(currency);[...] /* beaucoup de code... */ 530 Date d = new Date(); 531 if(test == 1) { 532 if(d.after(spotDate)) { 533 swap.setType("IRS"); 534 } else { 535 swap.setType("CURVE"); 536 } 537 } else if (test == 2) { 538 if(d.after(spotDate)) { 539 swap.setType("IRS"); 540 } else { 541 swap.setType("CURVE"); 542 } 543 }[...] /* encore beaucoup de code... */1135 return swap;1136 }

Page 104: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Test 2 public void can_parse_xml() throws Exception { 3 String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 4 "<!--\n" + 5 "\t== Copyright (c) 2002-2005. All rights reserved.\n" + 6 "\t== Financial Products Markup Language is subject to the FpML public license.\n" + 7 "\t== A copy of this license is available at http://www.fpml.org/documents/license\n" + 8 "-->\n" + 9 "<FpML version=\"4-2\" xmlns=\"http://www.fpml.org/2005/FpML-4-2\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.fpml.org/2005/FpML-4-2 fpml-main-4-2.xsd\" xsi:type=\"TradeCashflowsAsserted\">\n" +10 "\t<header>\n" +11 "\t\t<messageId messageIdScheme=\"http://www.example.com/messageId\">CEN/2004/01/05/15-38</messageId>\n" +12 "\t\t<sentBy>ABC</sentBy>\n" +13 "\t\t<sendTo>DEF</sendTo>\n" +14 "\t\t<creationTimestamp>2005-01-05T15:38:00-00:00</creationTimestamp>\n" +15 "\t</header>\n" +16 "\t<asOfDate>2005-01-05T15:00:00-00:00</asOfDate>\n" +17 "\t<tradeIdentifyingItems>\n" +18 "\t\t<partyTradeIdentifier>\n" +19 "\t\t\t<partyReference href=\"abc\"/>\n" +20 "\t\t\t<tradeId tradeIdScheme=\"http://www.abc.com/tradeId/\">trade1abcxxx</tradeId>\n" +21 "\t\t</partyTradeIdentifier>\n" +22 "\t\t<partyTradeIdentifier>\n" +23 "\t\t\t<partyReference href=\"def\"/>\n" +24 "\t\t\t<tradeId tradeIdScheme=\"http://www.def.com/tradeId/\">123cds</tradeId>\n" +25 "\t\t</partyTradeIdentifier>\n" +26 "\t</tradeIdentifyingItems>\n" +27 "\t<adjustedPaymentDate>2005-01-31</adjustedPaymentDate>\n" +28 "\t<netPayment>\n" +29 "\t\t<identifier netPaymentIdScheme=\"http://www.centralservice.com/netPaymentId\">netPaymentABCDEF001</identifier>\n" +30 "\t\t<payerPartyReference href=\"abc\"/>\n" +31 "\t\t<receiverPartyReference href=\"def\"/>\n" +32 "\t\t<paymentAmount>\n" +33 "\t\t\t<currency>EUR</currency>\n" +34 "\t\t\t<amount>200000</amount>\n" +35 "\t\t</paymentAmount>\n" +36 "\t</netPayment>\n" +

Page 105: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 106: Conf soat tests_unitaires_Mockito_jUnit_170113

code complexe 1 /** 2 * 3 * @param xml : document xml représentant le swap 4 * @return objet Swap 5 */ 6 public Swap parse(String xml) { 7 Swap swap = new Swap(); 8 String currency = getNodeValue("/swap/currency", xml); 9 swap.setCurrency(currency);[...] /* beaucoup de code... */ 530 Date d = new Date(); 531 if(test == 1) { 532 if(d.after(spotDate)) { 533 swap.setType("IRS"); 534 } else { 535 swap.setType("CURVE"); 536 } 537 } else if (test == 2) { 538 if(d.after(spotDate)) { 539 swap.setType("IRS"); 540 } else { 541 swap.setType("CURVE"); 542 } 543 }[...] /* encore beaucoup de code... */1135 return swap;1136 }

Page 107: Conf soat tests_unitaires_Mockito_jUnit_170113

1 /** 2 * 3 * @param xml : document xml représentant le swap 4 * @return objet Swap 5 */ 6 public Swap parse(String xml) { 7 Swap swap = new Swap(); 8 String currency = getNodeValue("/swap/currency", xml); 9 swap.setCurrency(currency);[...] /* beaucoup de code... */ 530 Date d = new Date(); 531 if(test == 1) { 532 if(d.after(spotDate)) { 533 swap.setType("IRS"); 534 } else { 535 swap.setType("CURVE"); 536 } 537 } else if (test == 2) { 538 if(d.after(spotDate)) { 539 swap.setType("IRS"); 540 } else { 541 swap.setType("CURVE"); 542 } 543 }[...] /* encore beaucoup de code... */1135 return swap;1136 }

code complexe 531 if(test == 1) { 532 if(d.after(spotDate)) { 533 swap.setType("IRS"); 534 } else { 535 swap.setType("CURVE"); 536 } 537 } else if (test == 2) { 538 if(d.after(spotDate)) { 539 swap.setType("IRS"); 540 } else { 541 swap.setType("CURVE"); 542 } 543 }

EXTRACT METHOD !

Page 108: Conf soat tests_unitaires_Mockito_jUnit_170113

code complexe 1 public void updateSwapType(Swap swapToUpdate, Date now, Date spotDate, int test) { 2 if(test == 1) { 3 if(now.after(spotDate)) { 4 swapToUpdate.setType("IRS"); 5 } else { 6 swapToUpdate.setType("CURVE"); 7 } 8 } else if (test == 2) { 9 if(now.after(spotDate)) {10 swapToUpdate.setType("IRS");11 } else {12 swapToUpdate.setType("CURVE");13 }14 }15 }

Page 109: Conf soat tests_unitaires_Mockito_jUnit_170113

code complexe

1 @Test2 public void can_update_swap_type() throws Exception {3 Swap swap = new Swap();4 Date now = simpleDateFormat.parse("2012-06-15");5 Date before = simpleDateFormat.parse("2012-05-05");6 service.updateSwapType(swap, now, before, 1);7 assertEquals("IRS", swap.getType());8 }

Page 110: Conf soat tests_unitaires_Mockito_jUnit_170113

LE CODE DOIT ÊTRE MODULAIRE

Page 111: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton 1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private DAOService daoService; 6 7 private ProductService() { 8 System.out.println("ProductService constructor"); 9 daoService = DAOService.getInstance();10 }11 12 public static ProductService getInstance() {13 return instance;14 }15 16 17 18 public Object getProduct(String id) {19 return daoService.getObject("product", id);20 }21 }

Page 112: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private DAOService daoService; 6 7 private ProductService() { 8 System.out.println("ProductService constructor"); 9 daoService = DAOService.getInstance();10 }11 12 public static ProductService getInstance() {13 return instance;14 }15 16 17 18 public Object getProduct(String id) {19 return daoService.getObject("product", id);20 }21 }

Singleton 3 private static ProductService instance = new ProductService();

Page 113: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private DAOService daoService; 6 7 private ProductService() { 8 System.out.println("ProductService constructor"); 9 daoService = DAOService.getInstance();10 }11 12 public static ProductService getInstance() {13 return instance;14 }15 16 17 18 public Object getProduct(String id) {19 return daoService.getObject("product", id);20 }21 }

Singleton 7 private ProductService() { 9 daoService = DAOService.getInstance();10 }

Page 114: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton 1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private DAOService daoService; 6 7 private ProductService() { 8 System.out.println("ProductService constructor"); 9 daoService = DAOService.getInstance();10 }11 12 public static ProductService getInstance() {13 return instance;14 }15 16 17 18 public Object getProduct(String id) {19 return daoService.getObject("product", id);20 }21 }

Page 115: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code

Page 116: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code ProductService

Page 117: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code ProductService DAOService

Page 118: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code ProductService DAOService

Page 119: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code ProductService DAOService

Page 120: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

Code ProductService DAOService

MockProductService

Page 121: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton

1 public void validateSwap(String id) {2 Swap swap = (Swap) ProductService.getInstance().getProduct(id);3 swap.updateState("VALIDATE");4 ProductService.getInstance().save(swap);5 }

Page 122: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public void validateSwap(String id) {2 Swap swap = (Swap) ProductService.getInstance().getProduct(id);3 swap.updateState("VALIDATE");4 ProductService.getInstance().save(swap);5 }

Singleton

ProductService.getInstance() 4 ProductService.getInstance()

COUPLAGE FORT

Page 123: Conf soat tests_unitaires_Mockito_jUnit_170113

Injection

1 private ProductService productService; 2 3 public void setProductService(ProductService injectedService) { 4 this.productService = injectedService; 5 } 6 7 public void validateSwap(String id) { 8 Swap swap = (Swap) productService.getProduct(id); 9 swap.updateState("VALIDATE");10 productService.save(swap);11 }

Page 124: Conf soat tests_unitaires_Mockito_jUnit_170113

1 private ProductService productService; 2 3 public void setProductService(ProductService injectedService) { 4 this.productService = injectedService; 5 } 6 7 public void validateSwap(String id) { 8 Swap swap = (Swap) productService.getProduct(id); 9 swap.updateState("VALIDATE");10 productService.save(swap);11 }

Injection

3 public void setProductService(ProductService injectedService) { 4 this.productService = injectedService; 5 }

INJECTION

Page 125: Conf soat tests_unitaires_Mockito_jUnit_170113

1 private ProductService productService; 2 3 public void setProductService(ProductService injectedService) { 4 this.productService = injectedService; 5 } 6 7 public void validateSwap(String id) { 8 Swap swap = (Swap) productService.getProduct(id); 9 swap.updateState("VALIDATE");10 productService.save(swap);11 }

Injection

8 Swap swap = (Swap) productService.getProduct(id);

UTILISATION

Page 126: Conf soat tests_unitaires_Mockito_jUnit_170113

Injection 1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

Page 127: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

Injection 4 @Mock 5 private ProductService productService;

MOCK

Page 128: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

Injection 1 @InjectMocks 2 private BankAccount bankAccount;

INJECTION AUTOMATIQUE DES MOCKS

Page 129: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

Injection 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);

Page 130: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

14 bankAccount.validateSwap("fakeId");

Injection

Page 131: Conf soat tests_unitaires_Mockito_jUnit_170113

Injection 1 @InjectMocks 2 private BankAccount bankAccount; 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(swap).when(productService).getProduct("fakeId");12 Mockito.doNothing().when(productService).save(swap);13 14 bankAccount.validateSwap("fakeId");15 16 assertEquals("VALIDATE", swap.getState());17 }

16 assertEquals("VALIDATE", swap.getState());

Page 132: Conf soat tests_unitaires_Mockito_jUnit_170113

YODA (C) DISNEY

Page 133: Conf soat tests_unitaires_Mockito_jUnit_170113

UTILISE L’INJECTION, LUKE

YODA (C) DISNEY

Page 134: Conf soat tests_unitaires_Mockito_jUnit_170113

Sans injecteur ?

1 public void validateSwap(String id) {2 Swap swap = (Swap) ProductService.getInstance().getProduct(id);3 swap.updateState("VALIDATE");4 ProductService.getInstance().save(swap);5 }

Page 135: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public void validateSwap(String id) {2 Swap swap = (Swap) ProductService.getInstance().getProduct(id);3 swap.updateState("VALIDATE");4 ProductService.getInstance().save(swap);5 }

Sans injecteur ?

ProductService.getInstance() 4 ProductService.getInstance()

EXTRACT METHOD !

Page 136: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public ProductService getProductService() {2 return ProductService.getInstance();3 }4 5 public void validateSwap(String id) {6 Swap swap = (Swap) getProductService().getProduct(id);7 swap.updateState("VALIDATE");8 getProductService().save(swap);9 }

Sans injecteur ?

1 public ProductService getProductService() {2 return ProductService.getInstance();3 } getProductService() 8 getProductService()

Page 137: Conf soat tests_unitaires_Mockito_jUnit_170113

Sans injecteur ? 1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

Page 138: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

Sans injecteur ? 1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3);

REDÉFINITION DES MÉTHODESPOSSIBLE

Page 139: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

Sans injecteur ? 11 Mockito.doReturn(productService).when(bankAccount).getProductService();

Page 140: Conf soat tests_unitaires_Mockito_jUnit_170113

1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

Sans injecteur ? 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);

Page 141: Conf soat tests_unitaires_Mockito_jUnit_170113

Sans injecteur ? 1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

16 bankAccount.validateSwap("fakeId");

Page 142: Conf soat tests_unitaires_Mockito_jUnit_170113

Sans injecteur ? 1 @Spy 2 private BankAccount bankAccount = new BankAccount("", 23, "", 3); 3 4 @Mock 5 private ProductService productService; 6 7 @Test 8 public void can_validate_swap() { 9 Swap swap = new Swap();10 11 Mockito.doReturn(productService).when(bankAccount).getProductService();12 13 Mockito.doReturn(swap).when(productService).getProduct("fakeId");14 Mockito.doNothing().when(productService).save(swap);15 16 bankAccount.validateSwap("fakeId");17 18 assertEquals("VALIDATE", swap.getState());19 }

18 assertEquals("VALIDATE", swap.getState());

Page 143: Conf soat tests_unitaires_Mockito_jUnit_170113

Avertissement

Page 144: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton ? 1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 return instance;11 }12 }

Page 145: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 return instance;11 }12 }

Singleton ? 3 private static ProductService instance = new ProductService();

CRÉATION DE L’INSTANCE AU CHARGEMENT DE LA CLASS

Page 146: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 return instance;11 }12 }

5 private ProductService() {

Singleton ?

INSTANCIATION IMPOSSIBLE

Page 147: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = null; 4 5 public ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 if(instance == null) {11 instance = new ProductService();12 }13 return instance;14 }15 }

Singleton ? 5 public ProductService() { 6 7 }

CONSTRUCTEUR PUBLIC

Page 148: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService { 2 3 private static ProductService instance = null; 4 5 public ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 if(instance == null) {11 instance = new ProductService();12 }13 return instance;14 }15 }

Singleton ? 9 public static ProductService getInstance() {10 if(instance == null) {11 instance = new ProductService();12 }13 return instance;14 }

CHARGEMENT TARDIF

Page 149: Conf soat tests_unitaires_Mockito_jUnit_170113

Singleton ? 1 public class ProductService { 2 3 private static ProductService instance = new ProductService(); 4 5 private ProductService() { 6 7 } 8 9 public static ProductService getInstance() {10 return instance;11 }12 }

Page 150: Conf soat tests_unitaires_Mockito_jUnit_170113

1 public class ProductService implements IProductService { 2 3 private static IProductService instance = new ProductService(); 4 5 private ProductService() { 6 7 } 8 9 public static IProductService getInstance() {10 return instance;11 }12 }

Singleton ? implements IProductService { 3 private static IProductService instance 9 public static IProductService getInstance() {10 return instance;11 } NIVEAU SUPPLÉMENTAIRE VIA

UNE INTERFACE

Page 151: Conf soat tests_unitaires_Mockito_jUnit_170113

LANCER UN TEST DOIT ÊTRE FACILE

Page 152: Conf soat tests_unitaires_Mockito_jUnit_170113

Tests dans son IDEECLIPSE

NETBEANS

INTELLIJ

Page 153: Conf soat tests_unitaires_Mockito_jUnit_170113

LE CODE DOIT TOUJOURS ÊTRE DÉPLOYABLE

Page 154: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

mvn install

Page 155: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

[INFO] ---------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ---------------------------------------------

Page 156: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

mvn install

Page 157: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

[INFO] ---------------------------------------------

[INFO] BUILD FAILURE

[INFO] ---------------------------------------------

Page 158: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

[INFO] ---------------------------------------------

[INFO] BUILD FAILURE

[INFO] ---------------------------------------------

WORKS ON

MY

MACHINE

Page 159: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

Déclenchement d’un build

Page 160: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

Déclenchement d’un build Compilation

Page 161: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

Déclenchement d’un build Compilation Test

Page 162: Conf soat tests_unitaires_Mockito_jUnit_170113

Intégration continue

Déclenchement d’un build Compilation Test

Déploiement

Analyse de code

Page 163: Conf soat tests_unitaires_Mockito_jUnit_170113
Page 164: Conf soat tests_unitaires_Mockito_jUnit_170113

AVOIR LA BONNE COUVERTURE

Page 165: Conf soat tests_unitaires_Mockito_jUnit_170113

80%DE COUVERTURE DE CODE

Page 166: Conf soat tests_unitaires_Mockito_jUnit_170113

80%DE COUVERTURE DE GETTER/SETTER

Page 167: Conf soat tests_unitaires_Mockito_jUnit_170113

TRAVAILLER EN BINÔME

Page 168: Conf soat tests_unitaires_Mockito_jUnit_170113

binomage (pair hero)

philosophie différente pour code identique

HTTP://WWW.SXC.HU/PHOTO/959091

Page 169: Conf soat tests_unitaires_Mockito_jUnit_170113

binomage (pair hero)

philosophie différente pour code identiqueLES COMMANDES

Page 170: Conf soat tests_unitaires_Mockito_jUnit_170113

binomage (pair hero)

philosophie différente pour code identique

LE PLAN DE VOL

Page 171: Conf soat tests_unitaires_Mockito_jUnit_170113

Ping Pong

Page 172: Conf soat tests_unitaires_Mockito_jUnit_170113

J’écris le test

Page 173: Conf soat tests_unitaires_Mockito_jUnit_170113

Il écrit l’implémentation

Page 174: Conf soat tests_unitaires_Mockito_jUnit_170113

J’écris le test

Page 175: Conf soat tests_unitaires_Mockito_jUnit_170113

Il écrit l’implémentation

Page 176: Conf soat tests_unitaires_Mockito_jUnit_170113

bref

Page 177: Conf soat tests_unitaires_Mockito_jUnit_170113

j’ai binômé

Page 178: Conf soat tests_unitaires_Mockito_jUnit_170113

6 mois plus tard...

Page 179: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 180: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 181: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 182: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 183: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 184: Conf soat tests_unitaires_Mockito_jUnit_170113

Bugs

0

22,5

45

67,5

90

Janvier Février Mars Avril Mai Juin

Bugs Satisfaction

Page 185: Conf soat tests_unitaires_Mockito_jUnit_170113

BRAVO À NOTRE ÉQUIPE DE CHOC !

Page 186: Conf soat tests_unitaires_Mockito_jUnit_170113

(POUR RÉSUMER)

Page 187: Conf soat tests_unitaires_Mockito_jUnit_170113

Installez Jenkins

Page 188: Conf soat tests_unitaires_Mockito_jUnit_170113

Automatisez votre build

Page 189: Conf soat tests_unitaires_Mockito_jUnit_170113

Écrivez votre 1er test

Page 190: Conf soat tests_unitaires_Mockito_jUnit_170113

(même si il est «trop» simple)

Page 191: Conf soat tests_unitaires_Mockito_jUnit_170113

HTTP://WWW.SXC.HU/PHOTO/664214

IL FAUT APPRENDRE À NAGER...

Page 192: Conf soat tests_unitaires_Mockito_jUnit_170113

...AVANT DE GAGNER DES COMPÉTITIONS

HTTP://WWW.SXC.HU/PHOTO/1008962

Page 193: Conf soat tests_unitaires_Mockito_jUnit_170113

( DEMO )

Page 195: Conf soat tests_unitaires_Mockito_jUnit_170113

@DWURSTEISEN