1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> 4 5 <head> 6 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> 7 <title>EasyMock 3.1 Readme</title> 8 <link rel="stylesheet" href="easymock.css" /> 9 </head> 10 <body><div class="bodywidth"> 11 12 <h2>EasyMock 3.1 Readme</h2> 13 14 <p>Documentation de la version 3.1 (2011-11-10)<br /> 15 © 2001-2011 <a href="http://www.offis.de">OFFIS</a>, <a href="http://tammofreese.de">Tammo Freese</a>, <a href="http://www.ossia-conseil.com/blog/henri/">Henri Tremblay</a>. 16 </p> 17 <p><i>Documentation traduite originellement de l'anglais par <a href="http://alexdp.free.fr">Alexandre de Pellegrin</a>. 18 Maintenue par Henri Tremblay.</i> 19 </p> 20 <p> 21 EasyMock est une librairie fournissant un moyen simple d'utiliser des Mock Objects pour 22 une interface ou classe donne. EasyMock est disponible sous <a href="http://www.apache.org/licenses/LICENSE-2.0.txt">license Apache 2</a>. 23 </p> 24 <p> 25 Les Mock Objects simulent le comportement du code 26 mtier et sont capables de vrifier s'il est utilis 27 comme prvu. 28 Les classes mtier peuvent tre testes 29 de faon isole en simulant leurs objets 30 lis par des Mock Objects. 31 </p> 32 <p> 33 crire et maintenir des Mock Objects est souvent une 34 tche pnible et source d'erreurs. EasyMock gnre les 35 Mock Objects dynamiquement - pas besoin de les crire, pas 36 de code gnr! 37 </p> 38 <h3> 39 Avantages d'EasyMock 40 </h3> 41 <ul> 42 <li>Pas d'criture manuelle des Mock Objects. 43 </li> 44 <li>Supporte le refactoring sur les Mock Objects : le code de test ne sera pas cass au runtime lors du renommage de 45 mthodes ou de la rorganisations de paramtres 46 </li> 47 <li>Supporte les valeurs de retour et les exceptions. 48 </li> 49 <li>Supporte la vrification de l'ordre d'appel des mthodes, sur un ou plusieurs Mock Objects. 50 </li> 51 </ul> 52 <h2> 53 Environnement Requis 54 </h2> 55 <ul> 56 <li>EasyMock 2 fonctionne uniquement avec Java 1.5.0 ou suprieur.</li> 57 <li>cglib (2.2) and Objenesis (1.2) doivent tre prsent dans le classpath pour faire du mocking de classes</li> 58 </ul> 59 <h2> 60 Installation 61 </h2> 62 <h3>Avec Maven</h3> 63 EasyMock est disponible dans le rfrentiel central de Maven. Ajoutez la dpendance 64 suivante votre pom.xml: 65 <pre> 66 <dependency> 67 <groupId>org.easymock</groupId> 68 <artifactId>easymock</artifactId> 69 <version>3.1</version> 70 <scope>test</scope> 71 </dependency> 72 </pre> 73 Vous pouvez, bien videmment, n'importe quel outil de gestion de dpendances compatible 74 avec le rfrentiel Maven. 75 <h3>Manuellement</h3> 76 <ul> 77 <li>Dcompressez le fichier zip d'EasyMock (<code>easymock-3.1.zip</code>).</li> 78 <li>Allez dans le rpertoire <code>easymock-3.1</code>.</li> 79 <li>Ajoutez le jar d'EasyMock (<code>easymock.jar</code>) votre classpath.</li> 80 <li>Pour pouvoir mocker des classes, ajoutez aussi <a href="http://www.objenesis.org">Objenesis</a> et <a href="http://cglib.sourceforge.net/">Cglib</a> votre classpath.</li> 81 <li>Les tests sont dans <code>easymock-3.1-tests.jar</code> et peuvent tre lancs l'aide d'un JUnit TestRunner 82 en ayant JUnit 4.7, EasyMock, cglib et Objenesis dans votre classpath.</li> 83 <li>Le code source d'EasyMock est situ dans <code>easymock-3.1-sources.jar</code>.</li> 84 </ul> 85 <h2> 86 Utilisation 87 </h2> 88 <p> 89 La plupart des lments d'un logiciel ne fonctionnent 90 pas de manire isole mais en collaboration avec 91 d'autres lments (objets lis) pour effectuer leur 92 tche. 93 Dans beaucoup de cas, nous ne nous soucions pas d'utiliser des objets 94 lis pour nos tests unitaires du moment 95 que nous avons confiance en eux. Si 96 ce n'est pas le cas, les Mock Objects peuvent nous aider 97 tester unitairement de faon isole. Les Mock Objects 98 remplacent les objets lis de l'lment test. 99 </p> 100 <p> 101 Les exemples suivants utilisent l'interface <code>Collaborator</code>: 102 </p> 103 <pre> 104 package org.easymock.samples; 105 106 public interface Collaborator { 107 void documentAdded(String title); 108 void documentChanged(String title); 109 void documentRemoved(String title); 110 byte voteForRemoval(String title); 111 byte[] voteForRemovals(String[] title); 112 } 113 </pre> 114 <p> 115 Les implmentations de cette interface sont des 116 objets lis (des listeners dans ce cas) la classe nomme <code>ClassUnderTest</code>: 117 </p> 118 <pre> 119 public class ClassUnderTest { 120 // ... 121 public void addListener(Collaborator listener) { 122 // ... 123 } 124 public void addDocument(String title, byte[] document) { 125 // ... 126 } 127 public boolean removeDocument(String title) { 128 // ... 129 } 130 public boolean removeDocuments(String[] titles) { 131 // ... 132 } 133 } 134 </pre> 135 <p> 136 Le code de la classe et de l'interface est disponible dans 137 le package <code>org.easymock.samples</code> dans <code>easymock-3.1-samples.jar</code> 138 inclue dans la livraison d'EasyMock. 139 </p> 140 <p> 141 Les exemples qui suivent supposent que vous tes familier avec le framework de test JUnit. 142 Bien que les tests montrs ici utilisent JUnit 4, vous pouvez galement utiliser JUnit 3 ou TestNG. 143 </p> 144 <h3> 145 Votre premier Mock Object 146 </h3> 147 <p> 148 Nous allons maintenant construire un cas de test et jouer avec pour 149 comprendre les fonctionnalits du package EasyMock. Le 150 fichier <code>easymock-3.1-samples.jar</code> contient une version modifie de ce test. 151 Notre premier test devra vrifier que la suppression d'un document non existant <strong>ne doit pas</strong> 152 provoquer la notification de l'objet li. Voici le test dans la dfinition du Mock Object: 153 </p> 154 <pre> 155 package org.easymock.samples; 156 157 import org.junit.*; 158 159 public class ExampleTest { 160 161 private ClassUnderTest classUnderTest; 162 private Collaborator mock; 163 164 @Before 165 public void setUp() { 166 classUnderTest = new ClassUnderTest(); 167 classUnderTest.addListener(mock); 168 } 169 170 @Test 171 public void testRemoveNonExistingDocument() { 172 // This call should not lead to any notification 173 // of the Mock Object: 174 classUnderTest.removeDocument("Does not exist"); 175 } 176 } 177 </pre> 178 <p> 179 Pour beaucoup de tests utilisant EasyMock, nous avons 180 uniquement besoin de l'import statique des mthodes de la classe 181 <code>org.easymock.EasyMock</code>. 182 Cette classe est la seule non interne et non dprcie d'EasyMock 2. 183 </p> 184 <pre> 185 import static org.easymock.EasyMock.*; 186 import org.junit.*; 187 188 public class ExampleTest { 189 190 private ClassUnderTest classUnderTest; 191 private Collaborator mock; 192 193 } 194 </pre> 195 <p> 196 Pour obtenir un Mock Object, il faut: 197 </p> 198 <ol> 199 <li>crer un Mock Object pour l'interface simuler, 200 </li> 201 <li>enregistrer le comportement attendu, puis 202 </li> 203 <li>basculer le Mock Object l'tat 'replay'. 204 </li> 205 </ol> 206 <p> 207 Voici le premier exemple: 208 </p> 209 <pre> 210 @Before 211 public void setUp() { 212 mock = createMock(Collaborator.class); // 1 213 classUnderTest = new ClassUnderTest(); 214 classUnderTest.addListener(mock); 215 } 216 217 @Test 218 public void testRemoveNonExistingDocument() { 219 // 2 (we do not expect anything) 220 replay(mock); // 3 221 classUnderTest.removeDocument("Does not exist"); 222 } 223 </pre> 224 <p> 225 Aprs activation l'tape 3, <code>mock</code> 226 est un Mock Object de l'interface <code>Collaborator</code> 227 qui n'attend aucun appel. Cela signifie que si nous changeons notre <code>ClassUnderTest</code> 228 pour appeler n'importe quelle mthode de l'interface, le Mock Object lvera 229 une <code>AssertionError</code>: 230 </p> 231 <pre> 232 java.lang.AssertionError: 233 Unexpected method call documentRemoved("Does not exist"): 234 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 235 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 236 at $Proxy0.documentRemoved(Unknown Source) 237 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentRemoved(ClassUnderTest.java:74) 238 at org.easymock.samples.ClassUnderTest.removeDocument(ClassUnderTest.java:33) 239 at org.easymock.samples.ExampleTest.testRemoveNonExistingDocument(ExampleTest.java:24) 240 ... 241 </pre> 242 243 <h3> 244 Ajouter un comportement 245 </h3> 246 <p> 247 crivons un second test. Si un document est ajout 248 la classe teste, nous nous attendons un appel 249 <code>mock.documentAdded()</code> 250 sur le Mock Object avec le titre du document en argument: 251 </p> 252 <pre> 253 @Test 254 public void testAddDocument() { 255 mock.documentAdded("New Document"); // 2 256 replay(mock); // 3 257 classUnderTest.addDocument("New Document", new byte[0]); 258 } 259 </pre> 260 <p> 261 Aussi, dans l'tape d'enregistrement (avant d'appeler <code>replay</code>), 262 le Mock Object ne se comporte pas comme<em></em> un Mock Object mais enregistre 263 les appels de mthode. Aprs l'appel <code>replay</code>, 264 il se comporte comme un Mock Object, vrifiant que les appels 265 de mthode attendus ont bien lieu. 266 </p> 267 <p> 268 Si <code>classUnderTest.addDocument("New Document", new byte[0])</code> 269 appelle la mthode attendue avec un mauvais argument, le 270 Mock Object lvera une <code>AssertionError</code>: 271 </p> 272 <pre> 273 java.lang.AssertionError: 274 Unexpected method call documentAdded("Wrong title"): 275 documentAdded("New Document"): expected: 1, actual: 0 276 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 277 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 278 at $Proxy0.documentAdded(Unknown Source) 279 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:61) 280 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:28) 281 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) 282 ... 283 </pre> 284 <p> 285 Tous les appels attendus n'ayant pas eu lieu sont montrs, ainsi 286 que tous les appels faits alors qu'ils taient non attendus 287 (aucun dans notre cas). Si l'appel la mthode est 288 effectu trop de fois, le Mock Object le signale 289 galement: 290 </p> 291 <pre> 292 java.lang.AssertionError: 293 Unexpected method call documentAdded("New Document"): 294 documentAdded("New Document"): expected: 1, actual: 2 295 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 296 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 297 at $Proxy0.documentAdded(Unknown Source) 298 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:62) 299 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:29) 300 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) 301 ... 302 </pre> 303 <h3> 304 Vrifier le comportement 305 </h3> 306 <p> 307 Il y a un type d'erreur dont nous ne nous sommes pas 308 proccups jusqu' prsent: si nous dcrivons un 309 comportement, nous voulons vrifier qu'il est bien respect. 310 Le test qui suit passe si une mthode du Mock Object est appele. 311 Pour vrifier cela, nous devons appeler <code>verify(mock)</code>: 312 </p> 313 <pre> 314 @Test 315 public void testAddDocument() { 316 mock.documentAdded("New Document"); // 2 317 replay(mock); // 3 318 classUnderTest.addDocument("New Document", new byte[0]); 319 verify(mock); 320 } 321 </pre> 322 <p> 323 Si la mthode du Mock Object n'est pas appele, 324 l'exception suivante sera leve : 325 </p> 326 <pre> 327 java.lang.AssertionError: 328 Expectation failure on verify: 329 documentAdded("New Document"): expected: 1, actual: 0 330 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) 331 at org.easymock.EasyMock.verify(EasyMock.java:536) 332 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:31) 333 ... 334 </pre> 335 <p> 336 Le message de l'exception liste tous les appels attendus qui n'ont pas eu lieu. 337 </p> 338 <h3> 339 Attendre un nombre explicite d'appels 340 </h3> 341 <p> 342 Jusqu' maintenant, nos tests ont t faits uniquement 343 sur un seul appel de mthode. Le test suivant 344 vrifiera que l'ajout d'un document dj existant 345 dclenche l'appel <code>mock.documentChanged()</code> 346 avec l'argument appropri. Pour en tre certain, nous 347 vrifions cela trois fois (aprs tout, c'est un exemple 348 ;-)): 349 </p> 350 <pre> 351 @Test 352 public void testAddAndChangeDocument() { 353 mock.documentAdded("Document"); 354 mock.documentChanged("Document"); 355 mock.documentChanged("Document"); 356 mock.documentChanged("Document"); 357 replay(mock); 358 classUnderTest.addDocument("Document", new byte[0]); 359 classUnderTest.addDocument("Document", new byte[0]); 360 classUnderTest.addDocument("Document", new byte[0]); 361 classUnderTest.addDocument("Document", new byte[0]); 362 verify(mock); 363 } 364 </pre> 365 <p> 366 Afin d'viter la rptition de <code>mock.documentChanged("Document")</code>, 367 EasyMock fournit un raccourci. Nous pouvons spcifier le nombre d'appel avec la mthode 368 <code>times(int times)</code> sur l'objet retourn par <code>expectLastCall()</code>. 369 Le code ressemble alors cela: 370 </p> 371 <pre> 372 @Test 373 public void testAddAndChangeDocument() { 374 mock.documentAdded("Document"); 375 mock.documentChanged("Document"); 376 expectLastCall().times(3); 377 replay(mock); 378 classUnderTest.addDocument("Document", new byte[0]); 379 classUnderTest.addDocument("Document", new byte[0]); 380 classUnderTest.addDocument("Document", new byte[0]); 381 classUnderTest.addDocument("Document", new byte[0]); 382 verify(mock); 383 } 384 </pre> 385 <p> 386 Si la mthode est appele un trop grand nombre de fois, 387 une exception sera leve nous indiquant que la mthode a 388 t appele trop de fois. 389 L'erreur est leve immdiatement aprs le premier 390 appel dpassant la limite: 391 </p> 392 <pre> 393 java.lang.AssertionError: 394 Unexpected method call documentChanged("Document"): 395 documentChanged("Document"): expected: 3, actual: 4 396 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 397 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 398 at $Proxy0.documentChanged(Unknown Source) 399 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentChanged(ClassUnderTest.java:67) 400 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:26) 401 at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) 402 ... 403 </pre> 404 <p> 405 S'il y a trop peu d'appels, <code>verify(mock)</code> 406 lve une <code>AssertionError</code>: 407 </p> 408 <pre> 409 java.lang.AssertionError: 410 Expectation failure on verify: 411 documentChanged("Document"): expected: 3, actual: 2 412 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) 413 at org.easymock.EasyMock.verify(EasyMock.java:536) 414 at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) 415 ... 416 </pre> 417 <h3> 418 Spcifier des valeurs de retour 419 </h3> 420 <p> 421 Pour spcifier des valeurs de retour, nous encapsulons l'appel attendu dans 422 <code>expect(T value)</code> et spcifions la valeur de retour avec la 423 mthode <code>andReturn(Object returnValue)</code> sur l'objet retourn par 424 <code>expect(T value)</code>. 425 </p> 426 <p> 427 Prenons par exemple la vrification du workflow lors de la suppression d'un document. 428 Si <code>ClassUnderTest</code> fait un appel pour supprimer un document, 429 il doit demander aux objets lis de voter pour cette suppression 430 par appel <code>byte voteForRemoval(String title)</code>. 431 Une rponse positive approuve la suppression. Si la somme de 432 toutes les rponses est positive, alors le document est 433 supprim et l'appel <code>documentRemoved(String title)</code> 434 est effectu sur les objets lis: 435 </p> 436 <pre> 437 @Test 438 public void testVoteForRemoval() { 439 mock.documentAdded("Document"); // expect document addition 440 // expect to be asked to vote for document removal, and vote for it 441 expect(mock.voteForRemoval("Document")).andReturn((byte) 42); 442 mock.documentRemoved("Document"); // expect document removal 443 replay(mock); 444 classUnderTest.addDocument("Document", new byte[0]); 445 assertTrue(classUnderTest.removeDocument("Document")); 446 verify(mock); 447 } 448 449 @Test 450 public void testVoteAgainstRemoval() { 451 mock.documentAdded("Document"); // expect document addition 452 // expect to be asked to vote for document removal, and vote against it 453 expect(mock.voteForRemoval("Document")).andReturn((byte) -42); 454 replay(mock); 455 classUnderTest.addDocument("Document", new byte[0]); 456 assertFalse(classUnderTest.removeDocument("Document")); 457 verify(mock); 458 } 459 </pre> 460 <p> 461 Le type de la valeur de retour est vrifi la 462 compilation. Par exemple, le code suivant ne compilera pas du fait que 463 le type fourni ne correspond au type retourn par la 464 mthode: 465 </p> 466 <pre> 467 expect(mock.voteForRemoval("Document")).andReturn("wrong type"); 468 </pre> 469 <p> 470 Au lieu d'appeler <code>expect(T value)</code> pour 471 rcuprer l'objet auquel affecter une valeur de retour, 472 nous pouvons aussi utiliser l'objet retourn par <code>expectLastCall()</code>. 473 Ainsi, au lieu de 474 </p> 475 <pre> 476 expect(mock.voteForRemoval("Document")).andReturn((byte) 42); 477 </pre> 478 <p> 479 nous pouvons crire 480 </p> 481 <pre> 482 mock.voteForRemoval("Document"); 483 expectLastCall().andReturn((byte) 42); 484 </pre> 485 <p> 486 Ce type d'criture doit uniquement tre utilis 487 si la ligne est trop longue car il n'inclut pas la vrification 488 du type la compilation. 489 </p> 490 <h3> 491 Travailler avec les exceptions 492 </h3> 493 <p> 494 Afin de spcifier les exceptions (plus prcisment: 495 les Throwables) devant tre leves, l'objet 496 retourn par <code>expectLastCall()</code> et <code>expect(T value)</code> 497 fournit la mthode <code>andThrow(Throwable throwable)</code>. 498 Cette mthode doit tre appele durant l'tape 499 d'enregistrement aprs l'appel au Mock Object pour lequel le <code>Throwable</code> 500 doit tre lev. 501 </p> 502 <p> 503 Les exception non "checkes" (comme <code>RuntimeException</code>, 504 <code>Error</code> ainsi que toutes leurs sous classes) peuvent 505 tre leves de n'importe quelle mthode. Les 506 exceptions "checkes" ne doivent tre leves que 507 pour mthodes o cela est prvu. 508 </p> 509 <h3> 510 Crer des valeurs de retour ou des exceptions 511 </h3> 512 <p> 513 Parfois, nous voulons que notre Mock Object retourne une valeur ou 514 lve une exception cre au moment de l'appel. 515 Depuis la version 2.2 d'EasyMock, l'objet retourn 516 par <code>expectLastCall()</code> et <code>expect(T value)</code> fournit la mthode 517 <code>andAnswer(IAnswer answer)</code> permettant de spcifier une implmentation 518 de l'interface <code>IAnswer</code> utilise pour crer 519 une valeur de retour ou une exception. 520 </p> 521 <p> 522 Au sein d'<code>IAnswer</code>, les arguments passs lors de l'appel au mock sont 523 disponibles via <code>EasyMock.getCurrentArguments()</code>. 524 Si vous utilisez cela, les refactorings du type rorganisation 525 de l'ordre des arguments briseront vos tests. Vous tes prvenu. 526 </p> 527 <p> 528 Une alternative <code>IAnswer</code> sont les mthodes <code>andDelegateTo</code> et 529 <code>andStubDelegateTo</code>. Elles permettent de dlguer un appel une 530 implmentation concrte de l'interface "mockes" et qui fournira la valeur de retour. 531 L'avantage est que les paramtres normalement rcupr avec <code>EasyMock.getCurrentArguments()</code> 532 pour <code>IAnswer</code> sont maintenant passs la mthode de l'implmentation concrte. 533 a supporte donc le refactoring. Le dsavantage est qu'il faut fournir une implmentation... 534 ce qui resemble un peu faire un mock la main. Ce que vous tentez d'viter en utilisant 535 EasyMock. Il peut aussi tre pnible d'implmenter l'interface si celle-ci beaucoup de mthodes. Finalement, 536 le type de l'implmentation ne peut tre vrifi statiquement par rapport au type du Mock Object. 537 Si pour une quelconque raison, la class concrte n'implmente plus la mthode sur laquelle est 538 dlgu l'appel, vous aurez une exception lors de la phase de "replay". Ce cas devrait toutefois 539 tre assez rare. 540 </p> 541 <p> 542 Pour bien comprendre les deux options, voici un exemple: 543 </p> 544 <pre> 545 List<String> l = createMock(List.class); 546 547 // andAnswer style 548 expect(l.remove(10)).andAnswer(new IAnswer<String>() { 549 public String answer() throws Throwable { 550 return getCurrentArguments()[0].toString(); 551 } 552 }); 553 554 // andDelegateTo style 555 expect(l.remove(10)).andDelegateTo(new ArrayList<String>() { 556 @Override 557 public String remove(int index) { 558 return Integer.toString(index); 559 } 560 }); 561 </pre> 562 <h3> 563 Changer de comportement sur le mme appel de mthode 564 </h3> 565 <p> 566 Il est galement possible de spcifier un changement de comportement pour une mthode. 567 Les mthodes <code>times</code>, <code>andReturn</code> et <code>andThrow</code> 568 peuvent tre chanes. Comme exemple, 569 nous dfinissons <code>voteForRemoval("Document")</code> pour 570 </p> 571 <ul> 572 <li>retourner 42 pour les trois premiers appels, 573 </li> 574 <li>lever une <code>RuntimeException</code> sur le quatrime appel, 575 </li> 576 <li>renvoyer -42 une fois. 577 </li> 578 </ul> 579 <pre> 580 expect(mock.voteForRemoval("Document")) 581 .andReturn((byte) 42).times(3) 582 .andThrow(new RuntimeException(), 4) 583 .andReturn((byte) -42); 584 </pre> 585 <h3> 586 tre plus permissif sur le nombre d'appels 587 </h3> 588 <p> 589 Afin d'tre plus permissif sur le nombre d'appels attendus, 590 des mthodes additionnelles peuvent tre 591 utilises la place de <code>times(int count)</code>: 592 </p> 593 <dl> 594 <dt><code>times(int min, int max)</code></dt> 595 <dd>pour attendre entre <code>min</code> and <code>max</code> appels,</dd> 596 <dt><code>atLeastOnce()</code></dt> 597 <dd>pour attendre au moins un appel, et</dd> 598 <dt><code>anyTimes()</code></dt> 599 <dd>pour attendre une quantit non dfinie d'appels.</dd> 600 </dl> 601 <p> 602 Si aucun nombre d'appels n'est explicitement dfini, 603 alors seul un appel est attendu. Pour le dfinir explicitement, 604 vous pouvez utiliser <code>once()</code> ou <code>times(1)</code>. 605 </p> 606 <h3> 607 Mocks stricts 608 </h3> 609 <p> 610 Sur un Mock Object retourn par <code>EasyMock.createMock()</code>, 611 l'ordre d'appel des mthodes n'est pas vrifi. 612 Si vous souhaitez avoir un Mock Object 'strict' vrifiant cet ordre, 613 utilisez <code>EasyMock.create<i>Strict</i>Mock()</code>.</p> 614 <p> 615 Lorsqu'un appel inattendu une mthode est fait sur 616 un Mock Object 'strict', le message de l'exception contient les appels 617 de mthode attendus ce moment, suivi du premier appel en 618 conflit. <code>verify(mock)</code> montre tous les appels de mthode manqus. 619 </p> 620 <h3> 621 Activer/Dsactiver la vrification de l'ordre d'appel des mthodes 622 </h3> 623 <p> 624 Il est parfois ncessaire qu'un Mock Object vrifie 625 l'ordre d'appel sur certains appels uniquement. Pendant la phase 626 d'enregistrement, vous pouvez activer la vrification de l'ordre 627 d'appel en utilisant <code>checkOrder(mock, true)</code> et la 628 dsactiver en utilisant <code>checkOrder(mock, false)</code>. 629 </p> 630 <p> 631 Il y a deux diffrences entre un Mock Object 'strict' et un Mock Object 'normal': 632 </p> 633 <ol> 634 <li> Un mock 'strict' a la vrification de l'ordre d'appel activ la cration. </li> 635 <li> Un mock 'strict' a la vrification de l'ordre d'appel activ aprs un reset (voir <em>Rutilisation d'un Mock Object</em>). </li> 636 </ol> 637 <h3> 638 Dfinir des comparateurs d'arguments pour plus de souplesse 639 </h3> 640 <p> 641 Pour vrifier la correspondance un appel de mthode prvu sur un Mock Object, 642 les arguments<code> de type Object</code> sont compars, par dfaut, avec 643 <code>equals()</code>. Cela peut introduire des problmes. Considrons l'exemple suivant: 644 </p> 645 <pre> 646 String[] documents = new String[] { "Document 1", "Document 2" }; 647 expect(mock.voteForRemovals(documents)).andReturn(42); 648 </pre> 649 <p> 650 Si la mthode est appele avec un autre tableau ayant le mme contenu, 651 cela provoque une exception du fait que <code>equals()</code> compare l'identit 652 des objets pour les tableaux: 653 </p> 654 <pre> 655 java.lang.AssertionError: 656 Unexpected method call voteForRemovals([Ljava.lang.String;@9a029e): 657 voteForRemovals([Ljava.lang.String;@2db19d): expected: 1, actual: 0 658 documentRemoved("Document 1"): expected: 1, actual: 0 659 documentRemoved("Document 2"): expected: 1, actual: 0 660 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 661 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 662 at $Proxy0.voteForRemovals(Unknown Source) 663 at org.easymock.samples.ClassUnderTest.listenersAllowRemovals(ClassUnderTest.java:88) 664 at org.easymock.samples.ClassUnderTest.removeDocuments(ClassUnderTest.java:48) 665 at org.easymock.samples.ExampleTest.testVoteForRemovals(ExampleTest.java:83) 666 ... 667 </pre> 668 <p> 669 Pour spcifier que seule l'galit de tableau 670 est ncessaire pour cet appel, utilisez la mthode 671 <code>aryEq</code>, importe statiquement de la classe <code>EasyMock</code>: 672 </p> 673 <pre> 674 String[] documents = new String[] { "Document 1", "Document 2" }; 675 expect(mock.voteForRemovals(aryEq(documents))).andReturn(42); 676 </pre> 677 <p> 678 Si vous souhaitez utiliser les comparateurs lors d'un appel, vous devez 679 en utiliser pour chaque argument de la mthode appele. 680 </p> 681 <p> 682 Voici quelques comparateurs prdfinis disponible: 683 </p> 684 <dl> 685 686 <dt><code>eq(X value)</code></dt> 687 <dd>Vrifie que la valeur reue gale la valeur attendue. Disponible pour tous les types primitifs et objets.</dd> 688 689 <dt><code>anyBoolean()</code>, <code>anyByte()</code>, <code>anyChar()</code>, <code>anyDouble()</code>, <code>anyFloat()</code>, <code>anyInt()</code>, <code>anyLong()</code>, <code>anyObject()</code>, <code>anyObject(Class clazz)</code>, <code>anyShort()</code></dt> 690 <dd>Laisse passer n'importe quelle valeur. Disponible pour tous les types primitifs et objets.</dd> 691 692 <dt><code>eq(X value, X delta)</code></dt> 693 <dd>Vrifie que la valeur reue gale la valeur attendue, plus ou moins un delta. Disponible pour les <code>float</code> et <code>double</code>.</dd> 694 695 <dt><code>aryEq(X value)</code></dt> 696 <dd>Vrifie que la valeur reue gale la valeur attendue en s'appuyant sur <code>Arrays.equals()</code>. Disponible pour les tableaux d'objets et de types primitifs.</dd> 697 698 <dt><code>isNull()</code>, <code>isNull(Class clazz)</code></dt> 699 <dd>Vrifie que la valeur reue est nulle. Disponible pour les objets.</dd> 700 701 <dt><code>notNull()</code>, <code>notNull(Class clazz)</code></dt> 702 <dd>Vrifie que la valeur reue n'est pas nulle. Disponible pour les objets.</dd> 703 704 <dt><code>same(X value)</code></dt> 705 <dd>Vrifie que la valeur reue est la mme que la value attendue. Disponible pour les objets.</dd> 706 707 <dt><code>isA(Class clazz)</code></dt> 708 <dd>Vrifie que la valeur reue est une instance de clazz ou d'une classe hrite ou implmente clazz. Disponible pour les objets.</dd> 709 710 <dt><code>lt(X value)</code>, <code>leq(X value)</code>, <code>geq(X value)</code>, <code>gt(X value)</code></dt> 711 <dd>Vrifie que la valeur reue est infrieure/infrieure ou gale/suprieure 712 ou gale/suprieure la valeur attendue. Disponible pour tous les types primitifs numriques et les implmentations de <code>Comparable</code>.</dd> 713 714 <dt><code>startsWith(String prefix), contains(String substring), endsWith(String suffix)</code></dt> 715 <dd>Vrifie que la valeur reue commence par/contient/se termine par la valeur attendue. Disponible pour les <code>String</code>s.</dd> 716 717 <dt><code>matches(String regex), find(String regex)</code></dt> 718 <dd>Vrifie que la valeur reue/une sous-chane de la valeur reue correspond l'expression r. Disponible pour les <code>String</code>s.</dd> 719 720 <dt><code>and(X first, X second)</code></dt> 721 <dd>Est valide si les rsultats des deux comparateurs utiliss en <code>first</code> et <code>second</code> sont vrifis. Disponible pour tous les types primitifs et objets.</dd> 722 723 <dt><code>or(X first, X second)</code></dt> 724 <dd>Est valide si l'un des rsultats des deux comparateurs utiliss en <code>first</code> et <code>second</code> est vrifi. Disponible pour tous les types primitifs et objets.</dd> 725 726 <dt><code>not(X value)</code></dt> 727 <dd>Est valide si le rsultat du comparateur utilis dans <code>value</code> est ngatif.</dd> 728 729 <dt><code>cmpEq(X value)</code></dt> 730 <dd>Vrifie que la valeur reue gale la valeur attendue du point de vue de <code>Comparable.compareTo(X o)</code>. Disponible pour tous les types primitifs numriques et les implmentations de <code>Comparable</code>.</dd> 731 732 <dt><code>cmp(X value, Comparator<X> comparator, LogicalOperator operator)</code></dt> 733 <dd>Vrifie que <code>comparator.compare(reue, value) operator 0</code> o <code>operator</code> est <,<=,>,>= ou ==.</dd> 734 735 <dt><code>capture(Capture<T> capture)</code>, <code>captureXXX(Capture<T> capture)</code></dt> 736 <dd>Laisse passer n'importe quelle valeur mais la capture dans le paramtre <code>Capture</code> pour un usage ultrieurs. Vous pouvez utiliser <code>and(someMatcher(...), capture(c))</code> pour 737 capturer le paramtre d'un appel de mthode en particulier. Vous pouvez aussi spcifier le <code>CaptureType</code> pour indiquer l'objet 738 <code>Capture</code> de conserver le premier (<code>FIRST</code>), le dernier (<code>LAST</code>), tous (<code>ALL</code>) ou aucun (<code>NONE</code>) des objets capturs</dd> 739 740 </dl> 741 742 <h3> 743 Dfinir son propre comparateur d'arguments 744 </h3> 745 <p> 746 Il peut tre intressant de dfinir son propre 747 comparateur d'argument. Prenons un comparateur dont le rle 748 serait de vrifier une exception par rapport son 749 type et message. Il pourrait tre utilis de la faon suivante: 750 </p> 751 <pre> 752 IllegalStateException e = new IllegalStateException("Operation not allowed.") 753 expect(mock.logThrowable(eqException(e))).andReturn(true); 754 </pre> 755 <p> 756 Deux tapes sont ncessaires pour raliser cela: le nouveau comparateur 757 doit tre dfini et la mthode statique <code>eqException</code> 758 doit tre dclare. 759 </p> 760 <p> 761 Pour dfinir le nouveau comparateur d'argument, nous implmentons l'interface <code>org.easymock.IArgumentMatcher</code>. 762 Cette interface contient deux mthodes: <code>matches(Object actual)</code>, vrifiant 763 que l'argument reu est bien celui attendu, et <code>appendTo(StringBuffer buffer)</code>, 764 ajoutant au StringBuffer une chane de caractres reprsentative du comparateur d'argument. 765 L'implmentation est la suivante : 766 </p> 767 <pre> 768 import org.easymock.IArgumentMatcher; 769 770 public class ThrowableEquals implements IArgumentMatcher { 771 private Throwable expected; 772 773 public ThrowableEquals(Throwable expected) { 774 this.expected = expected; 775 } 776 777 public boolean matches(Object actual) { 778 if (!(actual instanceof Throwable)) { 779 return false; 780 } 781 String actualMessage = ((Throwable) actual).getMessage(); 782 return expected.getClass().equals(actual.getClass()) 783 && expected.getMessage().equals(actualMessage); 784 } 785 786 public void appendTo(StringBuffer buffer) { 787 buffer.append("eqException("); 788 buffer.append(expected.getClass().getName()); 789 buffer.append(" with message \""); 790 buffer.append(expected.getMessage()); 791 buffer.append("\"")"); 792 793 } 794 } 795 </pre> 796 <p> 797 La mthode <code>eqException</code> doit instancier le 798 comparateur d'argument avec l'objet Throwable donn, le fournir 799 EasyMock via la mthode statique <code>reportMatcher(IArgumentMatcher matcher)</code> 800 et retourner une valeur afin d'tre utilise au sein de l'appel la mthode mocke 801 (typiquement <code>0</code>, <code>null</code> ou <code>false</code>). Une premire tentative ressemblerait ceci: 802 </p> 803 <pre> 804 public static Throwable eqException(Throwable in) { 805 EasyMock.reportMatcher(new ThrowableEquals(in)); 806 return null; 807 } 808 </pre> 809 <p> 810 Cependant, cela ne fonctionnerait que si la mthode <code>logThrowable</code> 811 de l'exemple acceptait <code>Throwable</code>s et quelque chose de plus spcifique du style de <code>RuntimeException</code>. 812 Dans ce dernier cas, le code de notre exemple ne compilerait pas: 813 </p> 814 <pre> 815 IllegalStateException e = new IllegalStateException("Operation not allowed.") 816 expect(mock.logThrowable(eqException(e))).andReturn(true); 817 </pre> 818 <p> 819 Java 5.0 la rescousse: Au lieu de dfinir <code>eqException</code> 820 avec un <code>Throwable</code> en paramtre, nous utilisons un type gnrique 821 qui hrite de <code>Throwable</code>: 822 </p> 823 <pre> 824 public static <T extends Throwable> T eqException(T in) { 825 reportMatcher(new ThrowableEquals(in)); 826 return null; 827 } 828 </pre> 829 <h3> 830 Rutilisation d'un Mock Object 831 </h3> 832 <p> 833 Les Mock Objects peuvent tre rinitialiss avec <code>reset(mock)</code>. 834 </p> 835 <p> 836 Au besoin, un Mock Object peut aussi tre converti d'un type l'autre en appelant <code>resetToNice(mock)</code>, 837 <code>resetToDefault(mock)</code> ou <code>resetToStrict(mock)</code>. 838 </p> 839 <h3> 840 Utilisation d'un comportement de "stub" pour les mthodes 841 </h3> 842 <p> 843 Dans certains cas, nous voudrions que nos Mock Object rpondent 844 certains appels, mais sans tenir compte du nombre de fois, de l'ordre 845 ni mme s'ils ont t eu lieu. 846 Ce comportement de "stub" peut tre dfini en utilisant 847 les mthodes <code>andStubReturn(Object value)</code>, 848 <code>andStubThrow(Throwable throwable)</code>, <code>andStubAnswer(IAnswer<t> answer)</code> 849 et <code>asStub()</code>. Le code suivant configure le Mock Object pour rpondre 42 850 <code>voteForRemoval("Document")</code> une fois et -1 pour tous les autres arguments: 851 </p> 852 <pre> 853 expect(mock.voteForRemoval("Document")).andReturn(42); 854 expect(mock.voteForRemoval(not(eq("Document")))).andStubReturn(-1); 855 </pre> 856 <h3> 857 Cration de mocks dits "gentils" 858 </h3> 859 <p> 860 Pour un Mock Object retourn par <code>createMock()</code>, le comportement par dfaut pour toutes 861 les mthodes est de lever une <code>AssertionError</code> pour tous les appels non prvus. 862 Si vous souhaitez avoir un Mock Object "gentil" autorisant, par dfaut, l'appel 863 toutes les mthodes et retournant la valeur vide approprie (<code>0</code>, <code>null</code> 864 ou <code>false</code>), utilisez <code>create<i>Nice</i>Mock()</code> au lieu de <code>createMock()</code>. 865 </p> 866 867 <a id="Object_Methods"/><h3>Mthodes de la classe Object</h3> 868 <p> 869 Les comportements des quatre mthodes <code>equals()</code>, 870 <code>hashCode()</code>, <code>toString()</code> et <code>finalize()</code> 871 ne peuvent tre changs sur des Mock Objects crs avec EasyMock, 872 mme si elles font partie de l'interface duquel le Mock Object est cr. 873 </p> 874 <h3>Vrifier l'ordre d'appel des mthodes entre plusieurs Mocks</h3> 875 <p> 876 Jusqu' prsent, nous avons vu un Mock Object comme tant 877 seul et configur par les mthodes statiques de la classe <code>EasyMock</code>. 878 Mais beaucoup de ces mthodes statiques font rfrence l'objet "control" 879 cach de chaque Mock Object et lui dlgue l'appel. Un 880 Mock Control est un objet implmentant l'interface <code>IMocksControl</code>. 881 </p> 882 <p> 883 Du coup, au lieu de 884 </p> 885 <pre> 886 IMyInterface mock = createStrictMock(IMyInterface.class); 887 replay(mock); 888 verify(mock); 889 reset(mock); 890 </pre> 891 <p> 892 nous pourrions utiliser le code quivalent: 893 </p> 894 <pre> 895 IMocksControl ctrl = createStrictControl(); 896 IMyInterface mock = ctrl.createMock(IMyInterface.class); 897 ctrl.replay(); 898 ctrl.verify(); 899 ctrl.reset(); 900 </pre> 901 <p> 902 L'interface <code>IMocksControl</code> permet de crer plus d'un seul Mock Object. 903 Ainsi, il est possible de vrifier l'ordre d'appel des mthodes entre les mocks. 904 Par exemple, configurons deux mock objects pour l'interface <code>IMyInterface</code> pour lesquels 905 nous attendons respectivement les appels <code>mock1.a()</code> et <code>mock2.a()</code>, 906 un nombre indfini d'appels <code>mock1.c()</code> et <code>mock2.c()</code>, 907 et enfin <code>mock2.b()</code> et <code>mock1.b()</code>, dans cet ordre: 908 </p> 909 <pre> 910 IMocksControl ctrl = createStrictControl(); 911 IMyInterface mock1 = ctrl.createMock(IMyInterface.class); 912 IMyInterface mock2 = ctrl.createMock(IMyInterface.class); 913 914 mock1.a(); 915 mock2.a(); 916 917 ctrl.checkOrder(false); 918 919 mock1.c(); 920 expectLastCall().anyTimes(); 921 mock2.c(); 922 expectLastCall().anyTimes(); 923 924 ctrl.checkOrder(true); 925 926 mock2.b(); 927 mock1.b(); 928 929 ctrl.replay(); 930 </pre> 931 <h3>Nommer un Mock Object</h3> 932 <p> 933 Les Mock Objects peuvent nomms leur cration en utilisant 934 <code>createMock(String name, Class<T> toMock)</code>, 935 <code>createStrictMock(String name, Class<T> toMock)</code> ou 936 <code>createNiceMock(String name, Class<T> toMock)</code>. 937 Les noms seront affichs dans le message des <code>AssertionError</code>. 938 </p> 939 <h3>Srializer un Mock Object</h3> 940 <p> 941 Un Mock Object peut tre srializ n'importe quelle tape de son 942 existence. Il y a toutefois des contraintes videntes: 943 </p> 944 <ul> 945 <li>Les comparateurs d'arguments utiliss doivent tre srializable (ceux fournis avec EasyMock le sont) 946 </li> 947 <li>Les paramtres enregistrs doivent tre srializable 948 </li> 949 </ul> 950 <h3>Traitement multifil</h3> 951 <p> 952 Pendant la phase d'enregistrement un Mock Object <b>n'est pas</b> fil scuris. Un Mock Object donn (ou des Mock Objects lis au 953 mme <code>IMocksControl</code>) ne peut tre enregistr que d'un seul fil. Toutefois, plusieurs Mock Objects peuvent tre enregistrs 954 simultanment dans des fils diffrents. 955 </p> 956 <p> 957 Durant la phase de rejeu, un Mock Object sera fil scuris par dfaut. Ceci peut tre chang en appelant <code>makeThreadSafe(mock, false)</code>. 958 durant la phase d'enregistrement. Cela peut permettre d'viter des interblocages dans certaines rares situations. 959 </p> 960 <p> 961 Finallement, appeler <code>checkIsUsedInOneThread(mock, true)</code> permet de s'assurer qu'un Mock Object ne sera appel que d'un seul 962 fil. Une exception sera lanc sinon. Cela peut tre pratique dans le cas o l'objet "mock" n'est pas fil scuris et que l'on veut 963 s'assurer qu'il est utilis correctement. 964 </p> 965 <h3>EasyMockSupport</h3> 966 <p> 967 <code>EasyMockSupport</code> est une classe ayant pour but d'tre utilise comme classe utilitaire ou comme classe de base de vos classes 968 de test. Elle se souvient de tous les "Mock Objects" crs (ou en fait de tous les "Mock Controls" crs) pour pouvoir faire un replay, 969 reset ou verify de tous en un seul coup. Voici un exemple utilisant JUnit: 970 </p> 971 <pre> 972 public class SupportTest extends EasyMockSupport { 973 974 private Collaborator firstCollaborator; 975 private Collaborator secondCollaborator; 976 private ClassTested classUnderTest; 977 978 @Before 979 public void setup() { 980 classUnderTest = new ClassTested(); 981 } 982 983 @Test 984 public void addDocument() { 985 // phase de cration 986 firstCollaborator = createMock(Collaborator.class); 987 secondCollaborator = createMock(Collaborator.class); 988 classUnderTest.addListener(firstCollaborator); 989 classUnderTest.addListener(secondCollaborator); 990 991 // phase d'enregistrement 992 firstCollaborator.documentAdded("New Document"); 993 secondCollaborator.documentAdded("New Document"); 994 995 replayAll(); // tous les mocks d'un seul coup 996 997 // test 998 classUnderTest.addDocument("New Document", new byte[0]); 999 1000 verifyAll(); // tous les mocks d'un seul coup 1001 } 1002 } 1003 </pre> 1004 <h3>Modifier les comportements par dfaut d'EasyMock</h3> 1005 <p> 1006 EasyMock fournit un mcanisme de gestion de proprits permettant de modifier son comportement. Il vise 1007 principalement permettre le retour un comportement antrieur la version courante. Les proprits 1008 actuellement supportes sont: 1009 </p> 1010 <dl> 1011 <dt><code>easymock.notThreadSafeByDefault</code></dt> 1012 <dd>Si true, les Mock Objects ne seront pas fil scuris par dfaut. Values possibles: "true" ou "false". Dfaut: false</dd> 1013 <dt><code>easymock.enableThreadSafetyCheckByDefault</code></dt> 1014 <dd>Si true, un mock ne pourra tre appel que d'un seul fil. Values possibles: "true" ou "false". Dfaut: false</dd> 1015 <dt><code>easymock.disableClassMocking</code></dt> 1016 <dd>Ne pas permettre le mocking de classes (permettre uniquement le mocking d'interfaces). Valeurs possibles: "true" ou "false". Dfaut: false</dd> 1017 </dl> 1018 <p> 1019 Les proprits peuvent tre mise de trois faons. Chaque tape de la liste peut craser une prcdente. 1020 </p> 1021 <ul> 1022 <li>Dans le fichier <code>easymock.properties</code> mis dans le package dfaut du classpath 1023 </li> 1024 <li>Comme proprit systme 1025 </li> 1026 <li>En appelant <code>EasyMock.setEasyMockProperty</code>. Des constantes sont disponibles 1027 dans la classe <code>EasyMock</code> 1028 </li> 1029 </ul> 1030 <h3> 1031 Compatibilit avec les anciennes versions 1032 </h3> 1033 <p>EasyMock 3 fournit toujours le project Class Extension (qui est toutefois dprci) pour 1034 permettre une migration plus facile de EasyMock 2 vers EasyMock 3. Il s'agit d'une compatibilit des 1035 sources et non des binaires. Le code devra donc tre recompil. 1036 </p> 1037 <p>EasyMock 2.1 introduisait une fonctionnalit de callback 1038 qui a t retire dans EasyMock 2.2, car trop complexe. 1039 Depuis EasyMock 2.2, l'interface <code>IAnswer</code> 1040 fournit la fonctionnalit de callback. 1041 </p> 1042 <h3>OSGi</h3> 1043 <p> 1044 Le jar d'EasyMock peut tre utilis comme bundle OSGi. Il export les packages 1045 <code>org.easymock</code>, <code>org.easymock.internal</code> 1046 et <code>org.easymock.internal.matchers</code>. Toutefois, pour importer les deux 1047 derniers, vous spcifier l'attribut <code>poweruser</code> "true" (<code>poweruser=true</code>). 1048 Ces packages sont prvus d'tre utiliss pour tendre EasyMock, ils n'ont donc pas besoins d'tre 1049 imports habituellement. 1050 </p> 1051 <h3>Mocking partiel</h3> 1052 <p> 1053 Dans certains cas, vous pouvez avoir besoin de "mocker" uniquement certaines 1054 mthodes d'une classe et de conserver un comportement normal pour 1055 les autres. Cela arrive habituellement lorsque pour souhaitez tester une 1056 mthode appelant d'autres mthodes de la mme classe. 1057 Vous voulez donc garder le comportement normal de la mthode teste 1058 et "mocker" les autres. 1059 </p> 1060 <p> 1061 Dans ce cas, la premier rflexe avoir est 1062 d'envisager un refactoring car, bien souvent, ce problme est la 1063 consquence d'un mauvais design. Si ce n'est pas le cas ou si 1064 vous ne pouvez faire autrement pour une quelconque contrainte de 1065 dveloppement, voici la solution: 1066 </p> 1067 <pre> 1068 ToMock mock = createMockBuilder(ToMock.class) 1069 .addMockedMethod("mockedMethod").createMock(); 1070 </pre> 1071 <p>Seules les mthodes ajoutes avec <code>addMockedMethod(s)</code> seront 1072 "mockes" (<code>mockedMethod()</code> dans l'exemple). Les autres conservent leur 1073 comportement habituel. Une exception: les mthodes abstraites sont "mockes" par dfaut. 1074 </p> 1075 <p><code>createMockBuilder</code> retourne l'interface <code>IMockBuilder</code>. Elle contient 1076 diverses mthodes pour facilement crer un mock partiel. Jettez un coup d'oeil la javadoc 1077 pour en savoir plus. 1078 </p> 1079 <p><b>Remarque:</b> EasyMock fournit un comportement par dfault pour les mthodes de la classe 1080 Object (<i>equals, hashCode, toString, finalize</i>). Toutefois, pour un mock partiel, si ces mthodes ne sont pas 1081 mockes explicitement, elles auront leur comportement normal et non celui par dfaut d'EasyMock. 1082 </p> 1083 <h3>Test interne d'une classe</h3> 1084 <p> 1085 Il est possible de crer un mock en appelant un constructeur de la classe. Ceci 1086 peut tre utile lorsqu'une mthode doit tre teste mais d'autres 1087 dans la mme classe "mockes". Pour cela vous devez faire quelque chose comme 1088 </p> 1089 <pre> 1090 ToMock mock = createMockBuilder(ToMock.class) 1091 .withConstructor(1, 2, 3); // 1, 2, 3 sont les paramtres passs au constructeur 1092 </pre> 1093 <p> 1094 Voir <code>ConstructorCalledMockTest</code> pour un exemple d'utilisation. 1095 </p> 1096 <h3>Remplacer l'instantiateur de classes par dfaut</h3> 1097 <p> 1098 Parfois (habituellement cause d'une JVM non supporte), il est possible 1099 que EasyMock ne soit pas capable de crer un mock dans votre environnement java. 1100 Sous le capot, l'instantiation de classes est implmente par un pattern "factory". 1101 En cas de problme, vous pouvez remplacer l'instantiateur par dfaut avec: 1102 </p> 1103 <ul> 1104 <li>L'ancien <code>DefaultClassInstantiator</code> qui fonctionne trs bien avec les classes 1105 srializable et sinon tente de deviner quel constructeur appeler et quels paramtres lui passer.</li> 1106 <li>Votre propre instantiateur. Celui-ci doit implmenter <code>IClassInstantiator</code>.</li> 1107 </ul> 1108 <p> 1109 Vous assignez ce nouvel instantiateur l'aide de <code>ClassInstantiatorFactory.setInstantiator()</code>. 1110 Vous pouvez remettre celui par dfaut avec <code>setDefaultInstantiator()</code>. 1111 </p> 1112 <p> 1113 <b>Important:</b> 1114 L'instantiateur est gard statiquement et reste donc entre deux tests. Assurez-vous 1115 de le rinitialiser si ncessaire. 1116 </p> 1117 <h3>Srializer une classe mocke</h3> 1118 <p> 1119 Une class mocke peut aussi tre srializ. Toutefois, comme celle-ci tant une classe srializable, 1120 cette dernire peut avoir un comportement spcial d l'implmentation de mthodes tels 1121 que <code>writeObject</code>. Ces mthodes seront toujours appeles lorsque le mock sera srializ 1122 et peuvent potentiellement chouer. Habituellement, le contournement consiste crer le mock 1123 en appelant un constructeur. 1124 </p> 1125 <p> 1126 Aussi, il est possible que la d-srialization d'un mock ne fonctionne pas si elle est effectue dans 1127 un class loader diffrent de la srialization. Ce cas n'a pas t test. 1128 </p> 1129 <h3>Limitations du mocking de classes</h3> 1130 <p> 1131 Pour tre cohrent avec le mocking d'interfaces, EasyMock fournit aussi un comportement par dfaut 1132 pour <code>equals()</code>, <code>toString()</code>, <code>hashCode()</code> et <code>finalize()</code> pour les classes mockes. 1133 Cela signifie que vous ne pourrez enregistrer votre propre comportement pour ces mthodes. Cette 1134 limitation tre considre comme une fonctionnalit permettant de ne pas s'occuper de ces 1135 mthodes. 1136 </p> 1137 <p> 1138 Les mthodes finales ne peuvent pas tre "mockes". Si 1139 appeles, leur code normal sera excut. 1140 </p> 1141 <p> 1142 Les mthodes prives ne peuvent tre "mockes". Si 1143 appeles, leur code normal sera excut. Pour un mock partiel, si 1144 la mthode teste appelle une mthode prive, vous devrez aussi tester 1145 cette dernire tant donn que vous ne pouvez pas la mocker. 1146 </p> 1147 <p> 1148 L'instantiation des classes est faite par 1149 <a href="http://objenesis.googlecode.com/svn/docs/index.html">Objenesis</a>. 1150 Les JVMs supportes sont listes <a href="http://code.google.com/p/objenesis/wiki/ListOfCurrentlySupportedVMs">ici</a>. 1151 </p> 1152 1153 <h2> 1154 Dveloppement d'EasyMock 1155 </h2> 1156 <p> 1157 EasyMock a t dvelopp par Tammo Freese chez OFFIS. La maintenance est effectue 1158 par Henri Tremblay depuis 2007. Le dveloppement d'EasyMock est hberg par 1159 <a href="http://sourceforge.net/projects/easymock/">SourceForge</a> 1160 pour permettre d'autres dveloppeurs et socits d'y contribuer. 1161 </p> 1162 <p> 1163 Les Mock Objects de classes (prcdemment appel EasyMock Class Extension) ont t initialement 1164 dveloppe par Joel Shellman, Chad Woolley et Henri Tremblay dans la section 1165 fichiers du of Yahoo!Groups. 1166 </p> 1167 <p> 1168 Remerciements ceux qui nous ont fourni retour d'exprience et rustines, incluant 1169 Nascif Abousalh-Neto, Dave Astels, Francois Beausoleil, George Dinwiddie, Shane Duan, 1170 Wolfgang Frech, Steve Freeman, Oren Gross, John D. Heintz, Dale King, Brian Knorr, 1171 Dierk Koenig, Chris Kreussling, Robert Leftwich, Patrick Lightbody, Johannes Link, 1172 Rex Madden, David McIntosh, Karsten Menne, Bill Michell, 1173 Stephan Mikaty, Ivan Moore, Ilja Preuss, Justin Sampson, Markus Schmidlin, Richard Scott, 1174 Joel Shellman, Ji Mare, Alexandre de Pellegrin 1175 Shaun Smith, Marco Struck, Ralf Stuckert, Victor Szathmary, Bill Uetrecht, 1176 Frank Westphal, Chad Woolley, Bernd Worsch, 1177 Rodrigo Damazio, Bruno Fonseca, Ben Hutchison et de nombreux autres. 1178 </p> 1179 <p> 1180 Merci de consulter la <a href="http://www.easymock.org">page d'accueil EasyMock</a> 1181 pour tre inform des nouvelles versions et transmettez vos bogues et suggestions 1182 <a href="mailto:easymock (a] yahoogroups.com?subject=EasyMock ${project.version} feedback">EasyMock Yahoo!Group</a> (en anglais SVP). 1183 Si vous souhaitez souscrire au EasyMock Yahoo!Group, envoyez un message 1184 <a href="mailto:easymock-subscribe (a] yahoogroups.com">easymock-subscribe (a] yahoogroups.com</a>. 1185 </p> 1186 <h3> 1187 EasyMock Version 3.1 (2011-11-10), Notes de Mise Jour 1188 </h3> 1189 <p> 1190 Nouveau dans la version 3.1: 1191 </p> 1192 <ul> 1193 <li>NoClassDefFoundError en appelant EasyMock.replay/reset/verify sur un mock d'interface si cglib n'est pas dans le classpath (EASYMOCK-40) 1194 </li> 1195 <li>Il est possible de compiler en Java 7 (les mthodes de capture des types primitifs sont renommes et dprcies) (EASYMOCK-100) 1196 </li> 1197 <li>Rparer la fuite mmoire lors de l'enregistrement du callback dans cglib (EASYMOCK-89) 1198 </li> 1199 <li>Ignorer les appels <code>finalize</code> sur un Mock Object (EASYMOCK-21) 1200 </li> 1201 <li>MockBuilder.addMockedMethod doit refuser les mthodes finales (EASYMOCK-44) 1202 </li> 1203 <li>Les mthodes "bridge" ne doivent pas tre considrer par MockBuilder.addMockedMethod (EASYMOCK-90) 1204 </li> 1205 <li>Faire un test basique avec PowerMock pour vrifier qu'il fonctionne correctement (EASYMOCK-88) 1206 </li> 1207 <li>Ajout du nom de classe ou interface dans les messages d'erreur pour chaque invocation (EASYMOCK-104) 1208 </li> 1209 </ul> 1210 <p> 1211 Nouveau dans la version 3.0: 1212 </p> 1213 <ul> 1214 <li>EasyMock CE is maintenant fusionn avec EasyMock (2325762) 1215 </li> 1216 <li>Ajout de "boolean capture(...)" par compltion (je ne pense pas que c'est utile) 1217 </li> 1218 <li>Impossible de rpondre en dlguant une mthode protge (2891256) 1219 </li> 1220 <li>Un chec lors de la phase d'enregistrement peut impacter les tests subsquents (2914683) 1221 </li> 1222 <li>Returner une erreur spcifique lorsqu'un null est enregistr comme retour sur une mthode retournant un type primitif (2936175) 1223 </li> 1224 <li>Dsactiver le mocking de classes l'aide de <code>EasyMock.DISABLE_CLASS_MOCKING</code> 1225 </li> 1226 <li>Retirer les classes dprcies d'EasyMock 1 1227 </li> 1228 <li>Ne pas lancer d'exception si on mock n'a pas de mthode <code>toString</code> (2937916) 1229 </li> 1230 <li>Message d'erreur plus clair lorsque des paramtres nues sont mlangs avec des matchers lors de l'enregistrement d'une mthode (2860190) 1231 </li> 1232 <li>Vrifier s'il reste des rsultats disponible dans un comportement enregistr avant de matcher avec celui-ci (2940400) 1233 </li> 1234 <li>Permettre les mocks de classes provenant d'un plugin Eclipse (2994002) 1235 </li> 1236 <li>Ajout de <code>isNull(Class<T>)</code>, <code>notNull(Class<T>)</code> et <code>anyObject(Class<T>)</code> pour faciliter la gestion des gnriques (2958636) 1237 </li> 1238 </ul> 1239 <p> 1240 Pour des notes de mise jour plus anciennes, voir la <a href="Documentation.html">documentation de EasyMock 2 et EasyMock 2 Class Extension</a>. 1241 </p> 1242 </div> 1243 </body> 1244 </html> 1245