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="en"> 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 for release 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> 18 EasyMock is a library that provides an easy way to use Mock Objects for given 19 interfaces or classes. EasyMock is available under the terms of the <a href="http://www.apache.org/licenses/LICENSE-2.0.txt">Apache 2 license</a>. 20 </p> 21 <p> 22 Mock Objects simulate parts of the behavior of domain code, 23 and are able to check whether they are used as defined. 24 Domain classes can be tested in isolation 25 by simulating their collaborators with Mock Objects. 26 </p> 27 <p> 28 Writing and maintaining Mock Objects often is a tedious 29 task that may introduce errors. EasyMock generates Mock Objects 30 dynamically - no need to write them, and no generated code! 31 </p> 32 <h2> 33 EasyMock Benefits 34 </h2> 35 <ul> 36 <li>Hand-writing classes for Mock Objects is not needed. 37 </li> 38 <li>Supports refactoring-safe Mock Objects: test code will not break at runtime when renaming methods or reordering method parameters 39 </li> 40 <li>Supports return values and exceptions. 41 </li> 42 <li>Supports checking the order of method calls, for one or more Mock Objects. 43 </li> 44 </ul> 45 <h2> 46 Requirements 47 </h2> 48 <ul> 49 <li>EasyMock only works with Java 1.5.0 and above.</li> 50 <li>cglib (2.2) and Objenesis (1.2) must be in the classpath to perform class mocking</li> 51 </ul> 52 <h2> 53 Installation 54 </h2> 55 <h3>Using Maven</h3> 56 EasyMock is available in the Maven central repository. Just add the following dependency to your pom.xml: 57 <pre> 58 <dependency> 59 <groupId>org.easymock</groupId> 60 <artifactId>easymock</artifactId> 61 <version>3.1</version> 62 <scope>test</scope> 63 </dependency> 64 </pre> 65 You can obviously use any other dependency tool compatible with the Maven repository. 66 67 <h3>Manually</h3> 68 <ul> 69 <li>Unzip the EasyMock zip file (<code>easymock-3.1.zip</code>).</li> 70 <li>Go into the <code>easymock-3.1</code> directory.</li> 71 <li>Add the EasyMock jar file (<code>easymock.jar</code>) to your classpath.</li> 72 <li>To perform class mocking, also add <a href="http://www.objenesis.org">Objenesis</a> and <a href="http://cglib.sourceforge.net/">Cglib</a> to your classpath.</li> 73 <li>The tests are in <code>easymock-3.1-tests.jar</code> and can be launched with a JUnit TestRunner 74 having JUnit 4.7 on top of EasyMock, cglib and Objenesis in your classpath.</li> 75 <li>The source code of EasyMock is stored in <code>easymock-3.1-sources.jar</code>.</li> 76 </ul> 77 <h2> 78 Usage 79 </h2> 80 <p> 81 Most parts of a software system do not work in isolation, but collaborate 82 with other parts to get their job done. In a lot of cases, we do not care 83 about using collaborators in unit testing, as we trust these collaborators. 84 If we <em>do</em> care about it, Mock Objects help us to test the unit under test 85 in isolation. Mock Objects replace collaborators of the unit under 86 test. 87 </p> 88 <p> 89 The following examples use the interface <code>Collaborator</code>: 90 </p> 91 <pre> 92 package org.easymock.samples; 93 94 public interface Collaborator { 95 void documentAdded(String title); 96 void documentChanged(String title); 97 void documentRemoved(String title); 98 byte voteForRemoval(String title); 99 byte[] voteForRemovals(String[] title); 100 } 101 </pre> 102 <p> 103 Implementors of this interface are collaborators 104 (in this case listeners) of a class named <code>ClassUnderTest</code>: 105 </p> 106 <pre> 107 public class ClassUnderTest { 108 // ... 109 public void addListener(Collaborator listener) { 110 // ... 111 } 112 public void addDocument(String title, byte[] document) { 113 // ... 114 } 115 public boolean removeDocument(String title) { 116 // ... 117 } 118 public boolean removeDocuments(String[] titles) { 119 // ... 120 } 121 } 122 </pre> 123 <p> 124 The code for both the class and the interface may be found 125 in the package <code>org.easymock.samples</code> in <code>easymock-3.1-samples.jar</code> 126 from the EasyMock zip delivery. 127 </p> 128 <p> 129 The following examples assume that you are familiar with the JUnit testing framework. 130 Although the tests shown here use JUnit 4, you may as well use JUnit 3 or TestNG. 131 </p> 132 <h3> 133 The first Mock Object 134 </h3> 135 <p> 136 We will now build a test case and toy around with it to understand the 137 functionality of the EasyMock package. <code>easymock-3.1-samples.jar</code> 138 contains a modified version of this test. Our first test should check 139 whether the removal of a non-existing document does <strong>not </strong> lead to a notification 140 of the collaborator. Here is the test without the definition of the 141 Mock Object: 142 </p> 143 <pre> 144 package org.easymock.samples; 145 146 import org.junit.*; 147 148 public class ExampleTest { 149 150 private ClassUnderTest classUnderTest; 151 private Collaborator mock; 152 153 @Before 154 public void setUp() { 155 classUnderTest = new ClassUnderTest(); 156 classUnderTest.addListener(mock); 157 } 158 159 @Test 160 public void testRemoveNonExistingDocument() { 161 // This call should not lead to any notification 162 // of the Mock Object: 163 classUnderTest.removeDocument("Does not exist"); 164 } 165 } 166 </pre> 167 <p> 168 For many tests using EasyMock, 169 we only need a static import of methods of <code>org.easymock.EasyMock</code>. 170 </p> 171 <pre> 172 import static org.easymock.EasyMock.*; 173 import org.junit.*; 174 175 public class ExampleTest { 176 177 private ClassUnderTest classUnderTest; 178 private Collaborator mock; 179 180 } 181 </pre> 182 <p> 183 To get a Mock Object, we need to 184 </p> 185 <ol> 186 <li>create a Mock Object for the interface we would like to simulate, 187 </li> 188 <li>record the expected behavior, and 189 </li> 190 <li>switch the Mock Object to replay state. 191 </li> 192 </ol> 193 <p> 194 Here is a first example: 195 </p> 196 <pre> 197 @Before 198 public void setUp() { 199 mock = createMock(Collaborator.class); // 1 200 classUnderTest = new ClassUnderTest(); 201 classUnderTest.addListener(mock); 202 } 203 204 @Test 205 public void testRemoveNonExistingDocument() { 206 // 2 (we do not expect anything) 207 replay(mock); // 3 208 classUnderTest.removeDocument("Does not exist"); 209 } 210 </pre> 211 <p> 212 After activation in step 3, <code>mock</code> 213 is a Mock Object for the <code>Collaborator</code> 214 interface that expects no calls. This means that if we change 215 our <code>ClassUnderTest</code> to call 216 any of the interface's methods, the Mock Object will throw 217 an <code>AssertionError</code>: 218 </p> 219 <pre> 220 java.lang.AssertionError: 221 Unexpected method call documentRemoved("Does not exist"): 222 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 223 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 224 at $Proxy0.documentRemoved(Unknown Source) 225 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentRemoved(ClassUnderTest.java:74) 226 at org.easymock.samples.ClassUnderTest.removeDocument(ClassUnderTest.java:33) 227 at org.easymock.samples.ExampleTest.testRemoveNonExistingDocument(ExampleTest.java:24) 228 ... 229 </pre> 230 231 <h3> 232 Adding Behavior 233 </h3> 234 <p> 235 Let us write a second test. If a document 236 is added on the class under test, we expect a call to <code>mock.documentAdded()</code> 237 on the Mock Object with the title of the document as argument: 238 </p> 239 <pre> 240 @Test 241 public void testAddDocument() { 242 mock.documentAdded("New Document"); // 2 243 replay(mock); // 3 244 classUnderTest.addDocument("New Document", new byte[0]); 245 } 246 </pre> 247 <p> 248 So in the record state (before calling <code>replay</code>), 249 the Mock Object does <em>not</em> behave like a Mock Object, 250 but it records method calls. After calling <code>replay</code>, 251 it behaves like a Mock Object, checking whether the expected 252 method calls are really done. 253 </p> 254 <p> 255 If <code>classUnderTest.addDocument("New Document", new byte[0])</code> 256 calls the expected method with a wrong argument, the Mock Object will complain 257 with an <code>AssertionError</code>: 258 </p> 259 <pre> 260 java.lang.AssertionError: 261 Unexpected method call documentAdded("Wrong title"): 262 documentAdded("New Document"): expected: 1, actual: 0 263 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 264 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 265 at $Proxy0.documentAdded(Unknown Source) 266 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:61) 267 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:28) 268 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) 269 ... 270 </pre> 271 <p> 272 All missed expectations are shown, as well as all fulfilled 273 expectations for the unexpected call (none in this case). If the method 274 call is executed too often, the Mock Object complains, too: 275 </p> 276 <pre> 277 java.lang.AssertionError: 278 Unexpected method call documentAdded("New Document"): 279 documentAdded("New Document"): expected: 1, actual: 2 280 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 281 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 282 at $Proxy0.documentAdded(Unknown Source) 283 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:62) 284 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:29) 285 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) 286 ... 287 </pre> 288 <h3> 289 Verifying Behavior 290 </h3> 291 <p> 292 There is one error that we have not handled so far: If we specify 293 behavior, we would like to verify that it is actually used. The current 294 test would pass if no method on the Mock Object is called. To verify that the 295 specified behavior has been used, we have to call 296 <code>verify(mock)</code>: 297 </p> 298 <pre> 299 @Test 300 public void testAddDocument() { 301 mock.documentAdded("New Document"); // 2 302 replay(mock); // 3 303 classUnderTest.addDocument("New Document", new byte[0]); 304 verify(mock); 305 } 306 </pre> 307 <p> 308 If the method is not called on the Mock Object, we now get the 309 following exception: 310 </p> 311 <pre> 312 java.lang.AssertionError: 313 Expectation failure on verify: 314 documentAdded("New Document"): expected: 1, actual: 0 315 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) 316 at org.easymock.EasyMock.verify(EasyMock.java:536) 317 at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:31) 318 ... 319 </pre> 320 <p> 321 The message of the exception lists all missed expectations. 322 </p> 323 <h3> 324 Expecting an Explicit Number of Calls 325 </h3> 326 <p> 327 Up to now, our test has only considered a single method call. The next 328 test should check whether the addition of an already existing 329 document leads to a call to <code>mock.documentChanged()</code> 330 with the appropriate argument. To be sure, we check this three 331 times (hey, it is an example ;-)): 332 </p> 333 <pre> 334 @Test 335 public void testAddAndChangeDocument() { 336 mock.documentAdded("Document"); 337 mock.documentChanged("Document"); 338 mock.documentChanged("Document"); 339 mock.documentChanged("Document"); 340 replay(mock); 341 classUnderTest.addDocument("Document", new byte[0]); 342 classUnderTest.addDocument("Document", new byte[0]); 343 classUnderTest.addDocument("Document", new byte[0]); 344 classUnderTest.addDocument("Document", new byte[0]); 345 verify(mock); 346 } 347 </pre> 348 <p> 349 To avoid the repetition of <code>mock.documentChanged("Document")</code>, 350 EasyMock provides a shortcut. We may specify the call count with the method 351 <code>times(int times)</code> on the object returned by 352 <code>expectLastCall()</code>. The code then looks like: 353 </p> 354 <pre> 355 @Test 356 public void testAddAndChangeDocument() { 357 mock.documentAdded("Document"); 358 mock.documentChanged("Document"); 359 expectLastCall().times(3); 360 replay(mock); 361 classUnderTest.addDocument("Document", new byte[0]); 362 classUnderTest.addDocument("Document", new byte[0]); 363 classUnderTest.addDocument("Document", new byte[0]); 364 classUnderTest.addDocument("Document", new byte[0]); 365 verify(mock); 366 } 367 </pre> 368 <p> 369 If the method is called too often, we get an exception that 370 tells us that the method has been called too many times. 371 The failure occurs immediately at the first method call 372 exceeding the limit: 373 </p> 374 <pre> 375 java.lang.AssertionError: 376 Unexpected method call documentChanged("Document"): 377 documentChanged("Document"): expected: 3, actual: 4 378 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 379 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 380 at $Proxy0.documentChanged(Unknown Source) 381 at org.easymock.samples.ClassUnderTest.notifyListenersDocumentChanged(ClassUnderTest.java:67) 382 at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:26) 383 at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) 384 ... 385 </pre> 386 <p> 387 If there are too few calls, <code>verify(mock)</code> 388 throws an <code>AssertionError</code>: 389 </p> 390 <pre> 391 java.lang.AssertionError: 392 Expectation failure on verify: 393 documentChanged("Document"): expected: 3, actual: 2 394 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) 395 at org.easymock.EasyMock.verify(EasyMock.java:536) 396 at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) 397 ... 398 </pre> 399 <h3> 400 Specifying Return Values 401 </h3> 402 <p> 403 For specifying return values, 404 we wrap the expected call in <code>expect(T value)</code> and specify the return value 405 with the method <code>andReturn(Object returnValue)</code> on the object returned by 406 <code>expect(T value)</code>. 407 </p> 408 <p> 409 As an example, we check the workflow for document 410 removal. If <code>ClassUnderTest</code> gets a call for document 411 removal, it asks all collaborators for their vote for removal 412 with calls to <code>byte voteForRemoval(String title)</code> value. 413 Positive return values are a vote for 414 removal. If the sum of all values is positive, the document is removed 415 and <code>documentRemoved(String title)</code> is called on 416 all collaborators: 417 </p> 418 <pre> 419 @Test 420 public void testVoteForRemoval() { 421 mock.documentAdded("Document"); // expect document addition 422 // expect to be asked to vote for document removal, and vote for it 423 expect(mock.voteForRemoval("Document")).andReturn((byte) 42); 424 mock.documentRemoved("Document"); // expect document removal 425 replay(mock); 426 classUnderTest.addDocument("Document", new byte[0]); 427 assertTrue(classUnderTest.removeDocument("Document")); 428 verify(mock); 429 } 430 431 @Test 432 public void testVoteAgainstRemoval() { 433 mock.documentAdded("Document"); // expect document addition 434 // expect to be asked to vote for document removal, and vote against it 435 expect(mock.voteForRemoval("Document")).andReturn((byte) -42); 436 replay(mock); 437 classUnderTest.addDocument("Document", new byte[0]); 438 assertFalse(classUnderTest.removeDocument("Document")); 439 verify(mock); 440 } 441 </pre> 442 <p> 443 The type of the returned value is checked at compile time. As an example, 444 the following code will not compile, as the type of the provided return value 445 does not match the method's return value: 446 </p> 447 <pre> 448 expect(mock.voteForRemoval("Document")).andReturn("wrong type"); 449 </pre> 450 <p> 451 Instead of calling <code>expect(T value)</code> 452 to retrieve the object for setting the return value, 453 we may also use the object returned by <code>expectLastCall()</code>. 454 Instead of 455 </p> 456 <pre> 457 expect(mock.voteForRemoval("Document")).andReturn((byte) 42); 458 </pre> 459 <p> 460 we may use 461 </p> 462 <pre> 463 mock.voteForRemoval("Document"); 464 expectLastCall().andReturn((byte) 42); 465 </pre> 466 <p> 467 This type of specification should only be used if the line gets too long, 468 as it does not support type checking at compile time. 469 </p> 470 <h3> 471 Working with Exceptions 472 </h3> 473 <p> 474 For specifying exceptions (more exactly: Throwables) to be thrown, the object returned by 475 <code>expectLastCall()</code> and <code>expect(T value)</code> provides the method 476 <code>andThrow(Throwable throwable)</code>. 477 The method has to be called in record state after the call to the Mock Object for 478 which it specifies the <code>Throwable</code> to be thrown. 479 </p> 480 <p> 481 Unchecked exceptions (that is, <code>RuntimeException</code>, <code>Error</code> 482 and all their subclasses) can be thrown from every method. Checked exceptions can only be 483 thrown from the methods that do actually throw them. 484 </p> 485 <h3> 486 Creating Return Values or Exceptions 487 </h3> 488 <p> 489 Sometimes we would like our mock object to return a value or throw an exception 490 that is created at the time of the actual call. Since EasyMock 2.2, the object returned by 491 <code>expectLastCall()</code> and <code>expect(T value)</code> provides the method 492 <code>andAnswer(IAnswer answer)</code> which allows to specify an implementation of the 493 interface <code>IAnswer</code> that is used to create the return value or exception. 494 </p> 495 <p> 496 Inside an <code>IAnswer</code> callback, the arguments passed to the mock call 497 are available via <code>EasyMock.getCurrentArguments()</code>. 498 If you use these, refactorings like reordering parameters may break your tests. 499 You have been warned. 500 </p> 501 <p> 502 An alternative to <code>IAnswer</code> are the <code>andDelegateTo</code> and 503 <code>andStubDelegateTo</code> methods. They allow to delegate the call to a 504 concrete implementation of the mocked interface that will then provide the answer. 505 The pros are that the arguments found in <code>EasyMock.getCurrentArguments()</code> 506 for <code>IAnswer</code> are now passed to the method of the concrete implementation. 507 This is refactoring safe. The cons are that you have to provide an implementation 508 which is kind of doing a mock manually... Which is what you try to avoid by 509 using EasyMock. It can also be painful if the interface has many methods. Finally, 510 the type of the concrete class can't be checked statically against the mock type. 511 If for some reason, the concrete class isn't implementing the method that is 512 delegated, you will get an exception during the replay only. However, this 513 case should be quite rare. 514 </p> 515 <p> 516 To understand correctly the two options, here is an example: 517 </p> 518 <pre> 519 List<String> l = createMock(List.class); 520 521 // andAnswer style 522 expect(l.remove(10)).andAnswer(new IAnswer<String>() { 523 public String answer() throws Throwable { 524 return getCurrentArguments()[0].toString(); 525 } 526 }); 527 528 // andDelegateTo style 529 expect(l.remove(10)).andDelegateTo(new ArrayList<String>() { 530 @Override 531 public String remove(int index) { 532 return Integer.toString(index); 533 } 534 }); 535 </pre> 536 <h3> 537 Changing Behavior for the Same Method Call 538 </h3> 539 <p> 540 It is also possible to specify a changing behavior for a method. 541 The methods <code>times</code>, <code>andReturn</code>, and <code>andThrow</code> 542 may be chained. As an example, we define <code>voteForRemoval("Document")</code> to 543 </p> 544 <ul> 545 <li>return 42 for the first three calls, 546 </li> 547 <li>throw a <code>RuntimeException</code> for the next four calls, 548 </li> 549 <li>return -42 once. 550 </li> 551 </ul> 552 <pre> 553 expect(mock.voteForRemoval("Document")) 554 .andReturn((byte) 42).times(3) 555 .andThrow(new RuntimeException(), 4) 556 .andReturn((byte) -42); 557 </pre> 558 <h3> 559 Relaxing Call Counts 560 </h3> 561 <p> 562 To relax the expected call counts, there are additional methods 563 that may be used instead of <code>times(int count)</code>: 564 </p> 565 <dl> 566 <dt><code>times(int min, int max)</code></dt> 567 <dd>to expect between <code>min</code> and <code>max</code> calls,</dd> 568 <dt><code>atLeastOnce()</code></dt> 569 <dd>to expect at least one call, and</dd> 570 <dt><code>anyTimes()</code></dt> 571 <dd>to expected an unrestricted number of calls.</dd> 572 </dl> 573 <p> 574 If no call count is specified, one call is expected. If we would like to state this 575 explicitely, <code>once()</code> or <code>times(1)</code> may be used. 576 </p> 577 <h3> 578 Strict Mocks 579 </h3> 580 <p> 581 On a Mock Object returned by a <code>EasyMock.createMock()</code>, 582 the order of method calls is not checked. 583 If you would like a strict Mock Object that checks the order of method calls, 584 use <code>EasyMock.create<i>Strict</i>Mock()</code> to create it.</p> 585 <p> 586 If an unexpected method is called on a strict Mock Object, 587 the message of the exception will show the method calls 588 expected at this point followed by the first conflicting one. 589 <code>verify(mock)</code> shows all missing method calls. 590 </p> 591 <h3> 592 Switching Order Checking On and Off 593 </h3> 594 <p> 595 Sometimes, it is necessary to have a Mock Object that checks the order of only some calls. 596 In record phase, you may switch order checking on by calling <code>checkOrder(mock, true)</code> 597 and switch it off by calling <code>checkOrder(mock, false)</code>. 598 </p> 599 <p> 600 There are two differences between a strict Mock Object and a normal Mock Object: 601 </p> 602 <ol> 603 <li> A strict Mock Object has order checking enabled after creation. </li> 604 <li> A strict Mock Object has order checking enabled after reset (see <em>Reusing a Mock Object</em>). </li> 605 </ol> 606 <h3> 607 Flexible Expectations with Argument Matchers 608 </h3> 609 <p> 610 To match an actual method call on the Mock Object with an 611 expectation, <code>Object</code> arguments are by default compared with 612 <code>equals()</code>. This may lead to problems. As an example, 613 we consider the following expectation: 614 </p> 615 <pre> 616 String[] documents = new String[] { "Document 1", "Document 2" }; 617 expect(mock.voteForRemovals(documents)).andReturn(42); 618 </pre> 619 <p> 620 If the method is called with another array with the same contents, 621 we get an exception, as <code>equals()</code> compares object 622 identity for arrays: 623 </p> 624 <pre> 625 java.lang.AssertionError: 626 Unexpected method call voteForRemovals([Ljava.lang.String;@9a029e): 627 voteForRemovals([Ljava.lang.String;@2db19d): expected: 1, actual: 0 628 documentRemoved("Document 1"): expected: 1, actual: 0 629 documentRemoved("Document 2"): expected: 1, actual: 0 630 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) 631 at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) 632 at $Proxy0.voteForRemovals(Unknown Source) 633 at org.easymock.samples.ClassUnderTest.listenersAllowRemovals(ClassUnderTest.java:88) 634 at org.easymock.samples.ClassUnderTest.removeDocuments(ClassUnderTest.java:48) 635 at org.easymock.samples.ExampleTest.testVoteForRemovals(ExampleTest.java:83) 636 ... 637 </pre> 638 <p> 639 To specify that only array equality is needed for this call, we may use the method 640 <code>aryEq</code> that is statically imported from the <code>EasyMock</code> class: 641 </p> 642 <pre> 643 String[] documents = new String[] { "Document 1", "Document 2" }; 644 expect(mock.voteForRemovals(aryEq(documents))).andReturn(42); 645 </pre> 646 <p> 647 If you would like to use matchers in a call, you have to specify matchers for all 648 arguments of the method call. 649 </p> 650 <p> 651 There are a couple of predefined argument matchers available. 652 </p> 653 <dl> 654 655 <dt><code>eq(X value)</code></dt> 656 <dd>Matches if the actual value is equals the expected value. Available for all primitive types and for objects.</dd> 657 658 <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> 659 <dd>Matches any value. Available for all primitive types and for objects.</dd> 660 661 <dt><code>eq(X value, X delta)</code></dt> 662 <dd>Matches if the actual value is equal to the given value allowing the given delta. Available for <code>float</code> and <code>double</code>.</dd> 663 664 <dt><code>aryEq(X value)</code></dt> 665 <dd>Matches if the actual value is equal to the given value according to <code>Arrays.equals()</code>. Available for primitive and object arrays.</dd> 666 667 <dt><code>isNull()</code>, <code>isNull(Class clazz)</code></dt> 668 <dd>Matches if the actual value is null. Available for objects.</dd> 669 670 <dt><code>notNull()</code>, <code>notNull(Class clazz)</code></dt> 671 <dd>Matches if the actual value is not null. Available for objects.</dd> 672 673 <dt><code>same(X value)</code></dt> 674 <dd>Matches if the actual value is the same as the given value. Available for objects.</dd> 675 676 <dt><code>isA(Class clazz)</code></dt> 677 <dd>Matches if the actual value is an instance of the given class, or if it is in instance of a class that extends or implements the given class. Null always return false. Available for objects.</dd> 678 679 <dt><code>lt(X value)</code>, <code>leq(X value)</code>, <code>geq(X value)</code>, <code>gt(X value)</code></dt> 680 <dd>Matches if the actual value is less/less or equal/greater or equal/greater than the given value. Available for all numeric primitive types and <code>Comparable</code>.</dd> 681 682 <dt><code>startsWith(String prefix), contains(String substring), endsWith(String suffix)</code></dt> 683 <dd>Matches if the actual value starts with/contains/ends with the given value. Available for <code>String</code>s.</dd> 684 685 <dt><code>matches(String regex), find(String regex)</code></dt> 686 <dd>Matches if the actual value/a substring of the actual value matches the given regular expression. Available for <code>String</code>s.</dd> 687 688 <dt><code>and(X first, X second)</code></dt> 689 <dd>Matches if the matchers used in <code>first</code> and <code>second</code> both match. Available for all primitive types and for objects.</dd> 690 691 <dt><code>or(X first, X second)</code></dt> 692 <dd>Matches if one of the matchers used in <code>first</code> and <code>second</code> match. Available for all primitive types and for objects.</dd> 693 694 <dt><code>not(X value)</code></dt> 695 <dd>Matches if the matcher used in <code>value</code> does not match.</dd> 696 697 <dt><code>cmpEq(X value)</code></dt> 698 <dd>Matches if the actual value is equals according to <code>Comparable.compareTo(X o)</code>. Available for all numeric primitive types and <code>Comparable</code>.</dd> 699 700 <dt><code>cmp(X value, Comparator<X> comparator, LogicalOperator operator)</code></dt> 701 <dd>Matches if <code>comparator.compare(actual, value) operator 0</code> where the operator is <,<=,>,>= or ==. Available for objects.</dd> 702 703 <dt><code>capture(Capture<T> capture)</code>, <code>captureXXX(Capture<T> capture)</code></dt> 704 <dd>Matches any value but captures it in the <code>Capture</code> parameter for later access. You can do <code>and(someMatcher(...), capture(c))</code> to 705 capture a parameter from a specific call to the method. You can also specify a <code>CaptureType</code> telling that a given <code>Capture</code> should keep 706 the first, the last, all or no captured values.</dd> 707 708 </dl> 709 710 <h3> 711 Defining your own Argument Matchers 712 </h3> 713 <p> 714 Sometimes it is desirable to define own argument matchers. Let's say that an 715 argument matcher is needed that matches an exception if the given exception has the same type and an equal message. 716 It should be used this way: 717 </p> 718 <pre> 719 IllegalStateException e = new IllegalStateException("Operation not allowed.") 720 expect(mock.logThrowable(eqException(e))).andReturn(true); 721 </pre> 722 <p> 723 Two steps are necessary to achieve this: The new argument matcher has to be defined, 724 and the static method <code>eqException</code> has to be declared. 725 </p> 726 <p> 727 To define the new argument matcher, we implement the interface <code>org.easymock.IArgumentMatcher</code>. 728 This interface contains two methods: <code>matches(Object actual)</code> checks whether the actual argument 729 matches the given argument, and <code>appendTo(StringBuffer buffer)</code> appends a string representation 730 of the argument matcher to the given string buffer. The implementation is straightforward: 731 </p> 732 <pre> 733 import org.easymock.IArgumentMatcher; 734 735 public class ThrowableEquals implements IArgumentMatcher { 736 private Throwable expected; 737 738 public ThrowableEquals(Throwable expected) { 739 this.expected = expected; 740 } 741 742 public boolean matches(Object actual) { 743 if (!(actual instanceof Throwable)) { 744 return false; 745 } 746 String actualMessage = ((Throwable) actual).getMessage(); 747 return expected.getClass().equals(actual.getClass()) 748 && expected.getMessage().equals(actualMessage); 749 } 750 751 public void appendTo(StringBuffer buffer) { 752 buffer.append("eqException("); 753 buffer.append(expected.getClass().getName()); 754 buffer.append(" with message \""); 755 buffer.append(expected.getMessage()); 756 buffer.append("\"")"); 757 758 } 759 } 760 </pre> 761 <p> 762 The method <code>eqException</code> must create the argument matcher with the given Throwable, 763 report it to EasyMock via the static method <code>reportMatcher(IArgumentMatcher matcher)</code>, 764 and return a value so that it may be used inside the call 765 (typically <code>0</code>, <code>null</code> or <code>false</code>). A first attempt may look like: 766 </p> 767 <pre> 768 public static Throwable eqException(Throwable in) { 769 EasyMock.reportMatcher(new ThrowableEquals(in)); 770 return null; 771 } 772 </pre> 773 <p> 774 However, this only works if the method <code>logThrowable</code> in the example usage accepts 775 <code>Throwable</code>s, and does not require something more specific like a <code>RuntimeException</code>. 776 In the latter case, our code sample would not compile: 777 </p> 778 <pre> 779 IllegalStateException e = new IllegalStateException("Operation not allowed.") 780 expect(mock.logThrowable(eqException(e))).andReturn(true); 781 </pre> 782 <p> 783 Java 5.0 to the rescue: Instead of defining <code>eqException</code> with a <code>Throwable</code> as 784 parameter and return value, we use a generic type that extends <code>Throwable</code>: 785 </p> 786 <pre> 787 public static <T extends Throwable> T eqException(T in) { 788 reportMatcher(new ThrowableEquals(in)); 789 return null; 790 } 791 </pre> 792 <h3> 793 Reusing a Mock Object 794 </h3> 795 <p> 796 Mock Objects may be reset by <code>reset(mock)</code>. 797 </p> 798 <p> 799 If needed, a mock can also be converted from one type to another by calling <code>resetToNice(mock)</code>, 800 <code>resetToDefault(mock)</code> ou <code>resetToStrict(mock)</code>. 801 </p> 802 <h3> 803 Using Stub Behavior for Methods 804 </h3> 805 <p> 806 Sometimes, we would like our Mock Object to respond to some method calls, but we do not want to 807 check how often they are called, when they are called, or even if they are called at all. 808 This stub behavoir may be defined by using the methods <code>andStubReturn(Object value)</code>, 809 <code>andStubThrow(Throwable throwable)</code>, <code>andStubAnswer(IAnswer<Tgt; answer)</code> 810 and <code>asStub()</code>. The following code 811 configures the MockObject to answer 42 to <code>voteForRemoval("Document")</code> once 812 and -1 for all other arguments: 813 </p> 814 <pre> 815 expect(mock.voteForRemoval("Document")).andReturn(42); 816 expect(mock.voteForRemoval(not(eq("Document")))).andStubReturn(-1); 817 </pre> 818 <h3> 819 Nice Mocks 820 </h3> 821 <p> 822 On a Mock Object returned by <code>createMock()</code> the default behavior for all methods is to throw an 823 <code>AssertionError</code> for all unexpected method calls. 824 If you would like a "nice" Mock Object that by default allows all method calls and returns 825 appropriate empty values (<code>0</code>, <code>null</code> or <code>false</code>), use <code>create<i>Nice</i>Mock()</code> instead. 826 </p> 827 828 <a id="Object_Methods"/><h3>Object Methods</h3> 829 <p> 830 The behavior for the four Object methods <code>equals()</code>, 831 <code>hashCode()</code>, <code>toString()</code> and <code>finalize()</code> 832 cannot be changed for Mock Objects created with EasyMock, 833 even if they are part of the interface for which the 834 Mock Object is created. 835 </p> 836 <h3>Checking Method Call Order Between Mocks</h3> 837 <p> 838 Up to this point, we have seen a mock object as a single object that is configured by static methods 839 on the class <code>EasyMock</code>. But many of these static methods just identify the hidden control of the Mock Object 840 and delegate to it. A Mock Control is an object implementing the <code>IMocksControl</code> interface. 841 </p> 842 <p> 843 So instead of 844 </p> 845 <pre> 846 IMyInterface mock = createStrictMock(IMyInterface.class); 847 replay(mock); 848 verify(mock); 849 reset(mock); 850 </pre> 851 <p> 852 we may use the equivalent code: 853 </p> 854 <pre> 855 IMocksControl ctrl = createStrictControl(); 856 IMyInterface mock = ctrl.createMock(IMyInterface.class); 857 ctrl.replay(); 858 ctrl.verify(); 859 ctrl.reset(); 860 </pre> 861 <p> 862 The IMocksControl allows to create more than one Mock Object, and so it is possible to check the order of method calls 863 between mocks. As an example, we set up two mock objects for the interface <code>IMyInterface</code>, and we expect the calls 864 <code>mock1.a()</code> and <code>mock2.a()</code> ordered, then an open number of calls to <code>mock1.c()</code> 865 and <code>mock2.c()</code>, and finally <code>mock2.b()</code> and <code>mock1.b()</code>, in this order: 866 </p> 867 <pre> 868 IMocksControl ctrl = createStrictControl(); 869 IMyInterface mock1 = ctrl.createMock(IMyInterface.class); 870 IMyInterface mock2 = ctrl.createMock(IMyInterface.class); 871 872 mock1.a(); 873 mock2.a(); 874 875 ctrl.checkOrder(false); 876 877 mock1.c(); 878 expectLastCall().anyTimes(); 879 mock2.c(); 880 expectLastCall().anyTimes(); 881 882 ctrl.checkOrder(true); 883 884 mock2.b(); 885 mock1.b(); 886 887 ctrl.replay(); 888 </pre> 889 <h3>Naming Mock Objects</h3> 890 <p> 891 Mock Objects can be named at creation using 892 <code>createMock(String name, Class<T> toMock)</code>, 893 <code>createStrictMock(String name, Class<T> toMock)</code> or 894 <code>createNiceMock(String name, Class<T> toMock)</code>. 895 The names will be shown in exception failures. 896 </p> 897 <h3>Serializing Mocks</h3> 898 <p> 899 Mocks can be serialized at any time during their life. However, there are some obvious contraints: 900 </p> 901 <ul> 902 <li>All used matchers should be serializable (all genuine EasyMock ones are) 903 </li> 904 <li>Recorded parameters should also be serializable 905 </li> 906 </ul> 907 <h3>Multithreading</h3> 908 <p> 909 During recording, a mock is <b>not</b> thread-safe. So a giving mock (or mocks linked to the same <code>IMocksControl</code>) 910 can only be recorded from a single thread. However, different mocks can be recorded simultaneously in different threads. 911 </p> 912 <p> 913 During the replay phase, mocks are by default thread-safe. This can be change for a given mock if <code>makeThreadSafe(mock, false)</code> 914 is called during the recording phase. This can prevent deadlocks in some rare situations. 915 </p> 916 <p> 917 Finally, calling <code>checkIsUsedInOneThread(mock, true)</code> on a mock will make sure the mock is used in only one thread and 918 throw an exception otherwise. This can be handy to make sure a thread-unsafe mocked object is used correctly. 919 </p> 920 <h3>EasyMockSupport</h3> 921 <p> 922 <code>EasyMockSupport</code> is a class that meant to be used as a helper or base class to your test cases. It will automatically registers all 923 created mocks (or in fact all created controls) and to replay, reset or verify them in batch instead of explicitly. Here's a JUnit example: 924 </p> 925 <pre> 926 public class SupportTest extends EasyMockSupport { 927 928 private Collaborator firstCollaborator; 929 private Collaborator secondCollaborator; 930 private ClassTested classUnderTest; 931 932 @Before 933 public void setup() { 934 classUnderTest = new ClassTested(); 935 } 936 937 @Test 938 public void addDocument() { 939 // creation phase 940 firstCollaborator = createMock(Collaborator.class); 941 secondCollaborator = createMock(Collaborator.class); 942 classUnderTest.addListener(firstCollaborator); 943 classUnderTest.addListener(secondCollaborator); 944 945 // recording phase 946 firstCollaborator.documentAdded("New Document"); 947 secondCollaborator.documentAdded("New Document"); 948 949 replayAll(); // replay all mocks at once 950 951 // test 952 classUnderTest.addDocument("New Document", new byte[0]); 953 954 verifyAll(); // verify all mocks at once 955 } 956 } 957 </pre> 958 <h3>Altering EasyMock default behavior</h3> 959 <p> 960 EasyMock provides a property mecanisim allowing to alter its behavior. It mainly aims 961 at allowing to use a legacy behavior on a new version. Currently supported properties are: 962 </p> 963 <dl> 964 <dt><code>easymock.notThreadSafeByDefault</code></dt> 965 <dd>If true, a mock won't be thread-safe by default. Possible values are "true" or "false". Default is false</dd> 966 <dt><code>easymock.enableThreadSafetyCheckByDefault</code></dt> 967 <dd>If true, thread-safety check feature will be on by default. Possible values are "true" or "false". Default is false</dd> 968 <dt><code>easymock.disableClassMocking</code></dt> 969 <dd>Do not allow class mocking (only allow interface mocking). Possible values are "true" or "false". Default is false.</dd> 970 </dl> 971 <p> 972 Properties can be set in three ways. Each step in the list can overwrite 973 previous ones. 974 </p> 975 <ul> 976 <li>In an <code>easymock.properties</code> file set in the classpath default package 977 </li> 978 <li>As a system property 979 </li> 980 <li>By calling <code>EasyMock.setEasyMockProperty</code>. Constants are available 981 in the <code>EasyMock</code> class 982 </li> 983 </ul> 984 <h3>Backward Compatibility</h3> 985 <p>EasyMock 3 still has a Class Extension project (although deprecated) to 986 allow an easier migration from EasyMock 2 to EasyMock 3. It is a source not a binary 987 compatibility. So the code will need to be recompiled. 988 </p> 989 <p>EasyMock 2.1 introduced a callback feature that has been removed in EasyMock 2.2, 990 as it was too complex. Since EasyMock 2.2, the <code>IAnswer</code> interface 991 provides the functionality for callbacks. 992 </p> 993 <h3>OSGi</h3> 994 <p> 995 EasyMock jar can be used as an OSGi bundle. It exports <code>org.easymock</code>, 996 <code>org.easymock.internal</code> and <code>org.easymock.internal.matchers</code> 997 packages. However, to import the two latter, you need to specify the <code>poweruser</code> 998 attribute at true (<code>poweruser=true</code>). These packages are meant to be 999 used to extend EasyMock so they usually don't need to be imported. 1000 </p> 1001 <h3>Partial mocking</h3> 1002 <p> 1003 Sometimes you may need to mock only some methods of a class and keep 1004 the normal behavior of others. This usually happens when you want to 1005 test a method that calls some others in the same class. So you want to 1006 keep the normal behavior of the tested method and mock the others. 1007 </p> 1008 <p> 1009 In this case, the first thing to do is to consider a refactoring since 1010 most of the time this problem caused by a bad design. If it's not 1011 the case or if you can't do otherwise because of some development constraints, 1012 here's the solution. 1013 </p> 1014 <pre> 1015 ToMock mock = createMockBuilder(ToMock.class) 1016 .addMockedMethod("mockedMethod").createMock(); 1017 </pre> 1018 <p>In this case only the methods added with <code>addMockedMethod(s)</code> will be 1019 mocked (<code>mockedMethod()</code> in the example). The others will still 1020 behave as they used to. One exception: abstract methods are conveniently mocked by default. 1021 </p> 1022 <p><code>createMockBuilder</code> returns a <code>IMockBuilder</code> interface. It contains various methods to 1023 easily create a partial mock. Have a look at the javadoc. 1024 </p> 1025 <p> 1026 <b>Remark:</b> EasyMock provides a default behavior for Object's methods (<i>equals, hashCode, toString, finalize</i>). 1027 However, for a partial mock, if these methods are not mocked explicitly, they will have their normal behavior 1028 instead of EasyMock default's one. 1029 </p> 1030 <h3>Self testing</h3> 1031 <p> 1032 It is possible to create a mock by calling one of its constructor. This can be handy when a 1033 class method needs to be tested but the class other methods, mocked. For that you should do 1034 something like 1035 </p> 1036 <pre> 1037 ToMock mock = createMockBuilder(ToMock.class) 1038 .withConstructor(1, 2, 3); // 1, 2, 3 are the constructor parameters 1039 </pre> 1040 <p> 1041 See the <code>ConstructorCalledMockTest</code> for an example. 1042 </p> 1043 <h3>Replace default class instantiator</h3> 1044 <p> 1045 For some reason (usually an unsupported JVM), it is possible that EasyMock isn't able to mock 1046 a class mock in your environment. Under the hood, class instantiation is implemented with a factory 1047 pattern. In case of failure, you can replace the default instantiator with: 1048 </p> 1049 <ul> 1050 <li>The good old <code>DefaultClassInstantiator</code> which works well with Serializable classes 1051 and otherwise tries to guess the best constructor and parameters to use.</li> 1052 <li>You own instantiator which only needs to implement <code>IClassInstantiator</code>.</li> 1053 </ul> 1054 <p> 1055 You set this new instantiator using <code>ClassInstantiatorFactory.setInstantiator()</code>. 1056 You can set back the default one with <code>setDefaultInstantiator()</code>. 1057 </p> 1058 <p> 1059 <b>Important:</b> 1060 The instantiator is kept statically so it will stick between your unit tests. Make sure you 1061 reset it if needed. 1062 </p> 1063 <h3>Serialize a class mock</h3> 1064 <p> 1065 A class mock can also be serialized. However, since it extends a serializable class, this class 1066 might have defined a special behavior using for instance <code>writeObject</code>. These methods 1067 will still be called when serializing the mock and might fail. The workaround is usually to call 1068 a constructor when creating the mock. 1069 </p> 1070 <p> 1071 Also, de-serializing the mock in a different class loader than the serialization might fail. It wasn't tested. 1072 </p> 1073 <h3>Class Mocking Limitations</h3> 1074 <ul> 1075 <li>To be coherent with interface mocking, EasyMock provides a built-in behavior 1076 for <code>equals()</code>, <code>toString()</code>, <code>hashCode()</code> and <code>finalize()</code> 1077 even for class mocking. It means that you cannot record your own behavior for 1078 these methods. This limitation is considered to be a feature 1079 that prevents you from having to care about these methods. 1080 </li> 1081 <li>Final methods cannot be mocked. If called, their normal code will be executed. 1082 </li> 1083 <li>Private methods cannot be mocked. If called, their normal code will be executed. 1084 During partial mocking, if your method under test is calling some private methods, 1085 you will need to test them as well since you cannot mock them. 1086 </li> 1087 <li>Class instantiation is performed using 1088 <a href="http://objenesis.googlecode.com/svn/docs/index.html">Objenesis</a>. 1089 Supported JVMs are listed 1090 <a href="http://code.google.com/p/objenesis/wiki/ListOfCurrentlySupportedVMs">here</a>. 1091 </li> 1092 </ul> 1093 1094 <h2> 1095 EasyMock Development 1096 </h2> 1097 <p> 1098 EasyMock has been developed by Tammo Freese at OFFIS. It is maintained by Henri Tremblay 1099 since 2007. The development of EasyMock is hosted on <a href="http://sourceforge.net/projects/easymock/">SourceForge</a> 1100 to allow other developers and companies to contribute. 1101 </p> 1102 <p> 1103 Class mocking (previously known as EasyMock Class Extension) was initially developed 1104 by Joel Shellman, Chad Woolley and Henri Tremblay on the files section of Yahoo!Groups. 1105 </p> 1106 <p> 1107 Thanks to the people who gave feedback or provided patches, including 1108 Nascif Abousalh-Neto, Dave Astels, Francois Beausoleil, George Dinwiddie, Shane Duan, 1109 Wolfgang Frech, Steve Freeman, Oren Gross, John D. Heintz, Dale King, Brian Knorr, 1110 Dierk Koenig, Chris Kreussling, Robert Leftwich, Patrick Lightbody, Johannes Link, 1111 Rex Madden, David McIntosh, Karsten Menne, Bill Michell, 1112 Stephan Mikaty, Ivan Moore, Ilja Preuss, Justin Sampson, Markus Schmidlin, Richard Scott, 1113 Joel Shellman, Ji Mare, Alexandre de Pellegrin 1114 Shaun Smith, Marco Struck, Ralf Stuckert, Victor Szathmary, Bill Uetrecht, 1115 Frank Westphal, Chad Woolley, Bernd Worsch, 1116 Rodrigo Damazio, Bruno Fonseca, Ben Hutchison and numerous others. 1117 </p> 1118 <p> 1119 Please check the <a href="http://www.easymock.org">EasyMock home page</a> for new versions, 1120 and send bug reports and suggestions to the 1121 <a href="mailto:easymock (a] yahoogroups.com?subject=EasyMock ${project.version} feedback">EasyMock Yahoo!Group</a>. 1122 If you would like to subscribe to the EasyMock Yahoo!Group, send a message to 1123 <a href="mailto:easymock-subscribe (a] yahoogroups.com">easymock-subscribe (a] yahoogroups.com</a>. 1124 </p> 1125 <h3> 1126 EasyMock Version 3.1 (2011-11-10) Release Notes 1127 </h3> 1128 <p> 1129 New in version 3.1: 1130 </p> 1131 <ul> 1132 <li>NoClassDefFoundError on calling EasyMock.replay/reset/verify on an interface mock without cglib in the classpath (EASYMOCK-40) 1133 </li> 1134 <li>Can compile in Java 7 (capture methods for primitive types are renamed and deprecated) (EASYMOCK-100) 1135 </li> 1136 <li>Fix memory leak in cglib callback registration process (EASYMOCK-89) 1137 </li> 1138 <li>Ignore calls to finalize on a mock (EASYMOCK-21) 1139 </li> 1140 <li>MockBuilder.addMockedMethod should fail for final methods (EASYMOCK-44) 1141 </li> 1142 <li>Bridge method should not be considered by MockBuilder.addMockedMethod (EASYMOCK-90) 1143 </li> 1144 <li>Perform a smoke test with PowerMock to make sure it is still working (EASYMOCK-88) 1145 </li> 1146 <li>Add the class or interface name in error message for each invocation (EASYMOCK-104) 1147 </li> 1148 </ul> 1149 <p> 1150 New in version 3.0: 1151 </p> 1152 <ul> 1153 <li>EasyMock CE is now merged into EasyMock (2325762) 1154 </li> 1155 <li>Add "boolean capture(...)" for completude (but I don't think it's useful) 1156 </li> 1157 <li>Can't answer by delegating to a protected method (2891256) 1158 </li> 1159 <li>Failure during recording phase can impact following tests (2914683) 1160 </li> 1161 <li>Return a specific error when null is recorded as return value on a method returning a primitive type (2936175) 1162 </li> 1163 <li>Can disable class mocking with <code>EasyMock.DISABLE_CLASS_MOCKING</code> 1164 </li> 1165 <li>Remove deprecated classes from EasyMock 1 1166 </li> 1167 <li>Should not fail on a mock not having a <code>toString</code> method (2937916) 1168 </li> 1169 <li>Improved error message when matchers are mixed with raw params during method recording (2860190) 1170 </li> 1171 <li>Check there are still results available in a recorded behaviour before trying to match with it (2940400) 1172 </li> 1173 <li>Allow to mock classes from an Eclipse plugin (2994002) 1174 </li> 1175 <li>Add <code>isNull(Class<T>)</code>, <code>notNull(Class<T>)</code> and <code>anyObject(Class<T>)</code> for easier generic handling (2958636) 1176 </li> 1177 </ul> 1178 <p> 1179 For older release notes, see <a href="Documentation.html">EasyMock 2 and EasyMock 2 Class Extension documentations</a>. 1180 </p> 1181 </div> 1182 </body> 1183 </html> 1184