View Javadoc
1   package mockit;
2   
3   import static org.junit.jupiter.api.Assertions.assertEquals;
4   import static org.junit.jupiter.api.Assertions.assertFalse;
5   import static org.junit.jupiter.api.Assertions.assertSame;
6   import static org.junit.jupiter.api.Assertions.assertTrue;
7   
8   import java.util.Date;
9   
10  import mockit.internal.util.ObjectMethods;
11  
12  import org.junit.jupiter.api.BeforeEach;
13  import org.junit.jupiter.api.Test;
14  
15  /**
16   * The Class ObjectOverridesTest.
17   */
18  public final class ObjectOverridesTest {
19  
20      /**
21       * Verify standard behavior of overridable object methods in mocked interface.
22       *
23       * @param r1
24       *            the r 1
25       * @param r2
26       *            the r 2
27       */
28      @Test
29      public void verifyStandardBehaviorOfOverridableObjectMethodsInMockedInterface(@Mocked Runnable r1,
30              @Mocked Runnable r2) {
31          assertDefaultEqualsBehavior(r1, r2);
32          assertDefaultEqualsBehavior(r2, r1);
33  
34          assertDefaultHashCodeBehavior(r1);
35          assertDefaultHashCodeBehavior(r2);
36  
37          assertDefaultToStringBehavior(r1);
38          assertDefaultToStringBehavior(r2);
39      }
40  
41      /**
42       * Assert default equals behavior.
43       *
44       * @param obj1
45       *            the obj 1
46       * @param obj2
47       *            the obj 2
48       */
49      @SuppressWarnings("SimplifiableJUnitAssertion")
50      void assertDefaultEqualsBehavior(Object obj1, Object obj2) {
51          assertFalse(obj1.equals(null));
52          assertFalse(obj1.equals("test"));
53          // noinspection EqualsWithItself
54          assertTrue(obj1.equals(obj1));
55          assertFalse(obj1.equals(obj2));
56      }
57  
58      /**
59       * Assert default hash code behavior.
60       *
61       * @param obj
62       *            the obj
63       */
64      void assertDefaultHashCodeBehavior(Object obj) {
65          assertEquals(System.identityHashCode(obj), obj.hashCode());
66      }
67  
68      /**
69       * Assert default to string behavior.
70       *
71       * @param obj
72       *            the obj
73       */
74      void assertDefaultToStringBehavior(Object obj) {
75          assertEquals(ObjectMethods.objectIdentity(obj), obj.toString());
76      }
77  
78      /**
79       * Verify standard behavior of overridden object methods in mocked JRE class.
80       *
81       * @param d1
82       *            the d 1
83       * @param d2
84       *            the d 2
85       */
86      @Test
87      public void verifyStandardBehaviorOfOverriddenObjectMethodsInMockedJREClass(@Mocked Date d1, @Mocked Date d2) {
88          assertDefaultEqualsBehavior(d1, d2);
89          assertDefaultEqualsBehavior(d2, d1);
90  
91          assertDefaultHashCodeBehavior(d1);
92          assertDefaultHashCodeBehavior(d2);
93  
94          assertDefaultToStringBehavior(d1);
95          assertDefaultToStringBehavior(d2);
96      }
97  
98      /** The a. */
99      @Mocked
100     ClassWithObjectOverrides a;
101 
102     /** The b. */
103     @Mocked
104     ClassWithObjectOverrides b;
105 
106     /**
107      * Call object methods in mock before every test.
108      */
109     @BeforeEach
110     void callObjectMethodsInMockBeforeEveryTest() {
111         assertEquals(System.identityHashCode(a), a.hashCode());
112         assertEquals(b, b);
113     }
114 
115     /**
116      * Verify standard behavior of overridden object methods in mocked class.
117      *
118      * @throws Throwable
119      *             the throwable
120      */
121     @Test
122     @SuppressWarnings("FinalizeCalledExplicitly")
123     void verifyStandardBehaviorOfOverriddenObjectMethodsInMockedClass() throws Throwable {
124         assertDefaultEqualsBehavior(a, b);
125         assertDefaultEqualsBehavior(b, a);
126 
127         assertDefaultHashCodeBehavior(a);
128         assertDefaultHashCodeBehavior(b);
129 
130         assertDefaultToStringBehavior(a);
131         assertDefaultToStringBehavior(b);
132 
133         a.finalize();
134         b.finalize();
135     }
136 
137     /**
138      * Mock override of equals method.
139      */
140     @Test
141     @SuppressWarnings({ "SimplifiableJUnitAssertion", "EqualsBetweenInconvertibleTypes" })
142     void mockOverrideOfEqualsMethod() {
143         new Expectations() {
144             {
145                 a.equals(null);
146                 result = true;
147                 a.equals(anyString);
148                 result = true;
149             }
150         };
151 
152         new Expectations() {
153             {
154                 b.equals(a);
155                 result = true;
156             }
157         };
158 
159         assertTrue(a.equals(null));
160         assertTrue(a.equals("test"));
161         assertTrue(b.equals(a));
162     }
163 
164     /**
165      * Mock override of hash code method.
166      */
167     @Test
168     void mockOverrideOfHashCodeMethod() {
169         assertTrue(a.hashCode() != b.hashCode());
170 
171         new Expectations() {
172             {
173                 a.hashCode();
174                 result = 123;
175                 b.hashCode();
176                 result = 45;
177                 times = 1;
178             }
179         };
180 
181         assertEquals(123, a.hashCode());
182         assertEquals(45, b.hashCode());
183     }
184 
185     /**
186      * Mock override of to string method.
187      */
188     @Test
189     void mockOverrideOfToStringMethod() {
190         // noinspection SimplifiableJUnitAssertion
191         assertFalse(a.toString().equals(b.toString()));
192 
193         new Expectations() {
194             {
195                 a.toString();
196                 result = "mocked";
197             }
198         };
199 
200         // noinspection SimplifiableJUnitAssertion
201         assertTrue("mocked".equals(a.toString()));
202 
203         new Verifications() {
204             {
205                 a.toString();
206                 b.toString();
207                 times = 0;
208             }
209         };
210     }
211 
212     /**
213      * Mock override of clone method.
214      */
215     @Test
216     void mockOverrideOfCloneMethod() {
217         new Expectations() {
218             {
219                 a.clone();
220                 result = b;
221             }
222         };
223 
224         assertSame(b, a.clone());
225     }
226 
227     /**
228      * Record expectations on overridden object method as always non strict.
229      */
230     @Test
231     void recordExpectationsOnOverriddenObjectMethodAsAlwaysNonStrict() {
232         new Expectations() {
233             {
234                 a.doSomething();
235                 a.hashCode();
236                 result = 1;
237                 a.equals(any);
238                 a.toString();
239             }
240         };
241 
242         a.doSomething();
243     }
244 
245     /**
246      * The Class ClassWithEqualsOverride.
247      */
248     @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
249     static class ClassWithEqualsOverride {
250 
251         /** The value. */
252         private final int value;
253 
254         /**
255          * Instantiates a new class with equals override.
256          *
257          * @param value
258          *            the value
259          */
260         ClassWithEqualsOverride(int value) {
261             this.value = value;
262         }
263 
264         @Override
265         public boolean equals(Object other) {
266             return ((ClassWithEqualsOverride) other).value == value;
267         }
268     }
269 
270     /**
271      * Partially mock instances of class with equals override whose instance gets passed in recorded expectation.
272      */
273     @Test
274     void partiallyMockInstancesOfClassWithEqualsOverrideWhoseInstanceGetsPassedInRecordedExpectation() {
275         final Object o1 = new ClassWithEqualsOverride(123);
276         Object o2 = new ClassWithEqualsOverride(123);
277 
278         new Expectations(o1, o2) {
279             {
280                 a.doSomething(o1);
281             }
282         };
283 
284         a.doSomething(o2);
285     }
286 
287     /**
288      * Partially mock instances of JRE class with equals override whose instance gets passed in recorded expectation.
289      */
290     @Test
291     void partiallyMockInstancesOfJREClassWithEqualsOverrideWhoseInstanceGetsPassedInRecordedExpectation() {
292         final Object o1 = new Date(123);
293         Object o2 = new Date(123);
294 
295         new Expectations(o1, o2) {
296             {
297                 a.doSomething(o1);
298             }
299         };
300 
301         a.doSomething(o2);
302     }
303 }