1 /*** 2 * Redistribution and use in source and binary forms, with or without 3 * modification, are permitted provided that the following conditions are 4 * met : 5 * 6 * . Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * 9 * . Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * . The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id: EasyMockTestCase.java,v 1.8 2005/08/26 18:09:37 mat007 Exp $ 29 */ 30 31 package jtge.util; 32 33 import java.util.IdentityHashMap; 34 import java.util.Iterator; 35 import junit.framework.TestCase; 36 import org.easymock.MockControl; 37 import org.easymock.classextension.MockClassControl; 38 39 /*** 40 * Extends a JUnit TestCase with several EasyMock related features. 41 * <p> 42 * This extension provides the following benefits : 43 * <ul> 44 * <li>supports interface and concrete classes through the same creation method 45 * <li>resets all expectations before each test 46 * <li>verifies all expectations after each test 47 * <li>provides helper methods to reset, replay or verify all control objects at once 48 * </ul> 49 * <p> 50 * As a consequence the tests are easier to write and end up being simpler. 51 * <p> 52 * TODO add nice and strict mock support 53 * 54 * @see <a href="http://junit.org">JUnit</a> 55 * @see <a href="http://easymock.org">EasyMock</a> 56 * @author Mathieu Champlon 57 * @version $Revision: 1.8 $ $Date: 2005/08/26 18:09:37 $ 58 */ 59 public class EasyMockTestCase extends TestCase 60 { 61 private final IdentityHashMap controls; 62 private boolean mustForceReplay; 63 64 /*** 65 * Create an easy mock test case. 66 */ 67 public EasyMockTestCase() 68 { 69 controls = new IdentityHashMap(); 70 mustForceReplay = true; 71 } 72 73 /*** 74 * {@inheritDoc} 75 */ 76 public final void runBare() throws Throwable 77 { 78 try 79 { 80 setUp(); 81 reset(); 82 try 83 { 84 runTest(); 85 } 86 finally 87 { 88 tearDown(); 89 } 90 if( mustForceReplay ) 91 replay(); 92 verify(); 93 } 94 finally 95 { 96 controls.clear(); 97 mustForceReplay = true; 98 } 99 } 100 101 /*** 102 * Factory method to create a mock object of a given type. 103 * 104 * @param type the type of the mock object to create 105 * @return the created mock object 106 */ 107 protected final Object createMock( final Class type ) 108 { 109 return register( createControl( type ) ); 110 } 111 112 private MockControl createControl( final Class type ) 113 { 114 if( type.isInterface() ) 115 return MockControl.createControl( type ); 116 return MockClassControl.createControl( type ); 117 } 118 119 private Object register( final MockControl control ) 120 { 121 final Object mock = control.getMock(); 122 controls.put( mock, control ); 123 return mock; 124 } 125 126 /*** 127 * Reset all mock objects expectations. 128 * <p> 129 * The state of mock objects is then the same as at the beginning of the test. 130 */ 131 protected final void reset() 132 { 133 mustForceReplay = true; 134 final Iterator iterator = controls.values().iterator(); 135 while( iterator.hasNext() ) 136 ((MockControl)iterator.next()).reset(); 137 } 138 139 /*** 140 * Set all mock objects to replay mode. 141 */ 142 protected final void replay() 143 { 144 mustForceReplay = false; 145 final Iterator iterator = controls.values().iterator(); 146 while( iterator.hasNext() ) 147 ((MockControl)iterator.next()).replay(); 148 } 149 150 /*** 151 * Verify all mock objects expectations. 152 * <p> 153 * This method is automatically called at the end of each test. 154 */ 155 protected final void verify() 156 { 157 final Iterator iterator = controls.values().iterator(); 158 while( iterator.hasNext() ) 159 ((MockControl)iterator.next()).verify(); 160 } 161 162 /*** 163 * Access the control object associated to a mock object. 164 * 165 * @param mock the mock object 166 * @return the control associated 167 */ 168 protected final MockControl control( final Object mock ) 169 { 170 return (MockControl)controls.get( mock ); 171 } 172 }