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