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.assertNotNull;
11  import static org.junit.jupiter.api.Assertions.assertNull;
12  import static org.junit.jupiter.api.Assertions.assertTrue;
13  
14  import java.beans.BeanInfo;
15  import java.beans.Introspector;
16  
17  import mockit.integration.junit5.JMockitExtension;
18  
19  import org.junit.jupiter.api.Test;
20  import org.junit.jupiter.api.extension.ExtendWith;
21  
22  /**
23   * The Class ExpectationsUsingMockedTest.
24   */
25  @ExtendWith(JMockitExtension.class)
26  class ExpectationsUsingMockedTest {
27  
28      /**
29       * The Interface Dependency.
30       */
31      public interface Dependency {
32          /**
33           * Do something.
34           *
35           * @param b
36           *            the b
37           *
38           * @return the string
39           */
40          String doSomething(boolean b);
41      }
42  
43      /**
44       * The Class AbstractBase.
45       */
46      public abstract static class AbstractBase {
47  
48          /**
49           * Adds the.
50           *
51           * @param i
52           *            the i
53           *
54           * @return true, if successful
55           */
56          protected abstract boolean add(Integer i);
57  
58          /**
59           * Do something.
60           *
61           * @return the int
62           */
63          final int doSomething() {
64              return -1;
65          }
66      }
67  
68      /** The base. */
69      @Mocked
70      AbstractBase base;
71  
72      /**
73       * Multiple mock parameters of same mocked type.
74       *
75       * @param dependency1
76       *            the dependency 1
77       * @param dependency2
78       *            the dependency 2
79       */
80      @Test
81      void multipleMockParametersOfSameMockedType(@Mocked final Dependency dependency1,
82              @Mocked final Dependency dependency2) {
83          new Expectations() {
84              {
85                  dependency1.doSomething(true);
86                  result = "1";
87                  dependency2.doSomething(false);
88                  result = "2";
89              }
90          };
91  
92          assertEquals("1", dependency1.doSomething(true));
93          assertNull(dependency1.doSomething(false));
94          assertEquals("2", dependency2.doSomething(false));
95          assertNull(dependency2.doSomething(true));
96      }
97  
98      /**
99       * Mock field for abstract class.
100      */
101     @Test
102     void mockFieldForAbstractClass() {
103         new Expectations() {
104             {
105                 base.add(1);
106                 result = true;
107             }
108         };
109 
110         assertFalse(base.add(0));
111         assertTrue(base.add(1));
112         assertFalse(base.add(2));
113     }
114 
115     static class ClassWithStaticInitializer {
116         static boolean initialized = true;
117 
118         static int initialized() {
119             return initialized ? 1 : -1;
120         }
121     }
122 
123     @Test
124     public void stubOutStaticInitializersWhenSpecified(
125             @Mocked(stubOutClassInitialization = true) ClassWithStaticInitializer unused) {
126         assertEquals(0, ClassWithStaticInitializer.initialized());
127         assertFalse(ClassWithStaticInitializer.initialized);
128     }
129 
130     /**
131      * The Class ClassWithStaticInitializer2.
132      */
133     static class ClassWithStaticInitializer2 {
134 
135         /** The initialized. */
136         static boolean initialized = true;
137 
138         /**
139          * Initialized.
140          *
141          * @return the int
142          */
143         static int initialized() {
144             return initialized ? 1 : -1;
145         }
146     }
147 
148     /**
149      * Do not stub out static initializers by default.
150      *
151      * @param unused
152      *            the unused
153      */
154     @Test
155     void doNotStubOutStaticInitializersByDefault(@Mocked ClassWithStaticInitializer2 unused) {
156         assertEquals(0, ClassWithStaticInitializer2.initialized());
157         assertTrue(ClassWithStaticInitializer2.initialized);
158     }
159 
160     /**
161      * The Class AnotherClassWithStaticInitializer.
162      */
163     static class AnotherClassWithStaticInitializer {
164 
165         /** The initialized. */
166         static boolean initialized = true;
167 
168         /**
169          * Initialized.
170          *
171          * @return the int
172          */
173         static int initialized() {
174             return initialized ? 1 : -1;
175         }
176     }
177 
178     /**
179      * Mock everything without stubbing static initializers.
180      *
181      * @param unused
182      *            the unused
183      */
184     @Test
185     void mockEverythingWithoutStubbingStaticInitializers(@Mocked AnotherClassWithStaticInitializer unused) {
186         assertEquals(0, AnotherClassWithStaticInitializer.initialized());
187         assertTrue(AnotherClassWithStaticInitializer.initialized);
188     }
189 
190     static class AnotherClassWithStaticInitializer2 {
191         static boolean initialized = true;
192 
193         static int initialized() {
194             return initialized ? 1 : -1;
195         }
196     }
197 
198     @Test
199     @SuppressWarnings("DefaultAnnotationParam")
200     public void avoidStubbingStaticInitializersThroughSpecificAnnotationAttribute(
201             @Mocked(stubOutClassInitialization = false) AnotherClassWithStaticInitializer2 unused) {
202         assertEquals(0, AnotherClassWithStaticInitializer2.initialized());
203         assertTrue(AnotherClassWithStaticInitializer2.initialized);
204     }
205 
206     /**
207      * The Class InnerClass.
208      */
209     static class InnerClass {
210         /**
211          * Gets the value.
212          *
213          * @return the value
214          */
215         int getValue() {
216             return -1;
217         }
218     }
219 
220     /**
221      * Mock inner class.
222      *
223      * @param innerMock
224      *            the inner mock
225      */
226     @Test
227     void mockInnerClass(@Mocked final InnerClass innerMock) {
228         assertEquals(0, innerMock.getValue());
229 
230         new Expectations() {
231             {
232                 innerMock.getValue();
233                 result = 123;
234                 times = 1;
235             }
236         };
237 
238         assertEquals(123, new InnerClass().getValue());
239     }
240 
241     /**
242      * The Class SubClass.
243      */
244     static final class SubClass extends AbstractBase {
245         @Override
246         protected boolean add(Integer i) {
247             return false;
248         }
249     }
250 
251     /**
252      * Record method from abstract base class and replay on subclass.
253      */
254     @Test
255     void recordMethodFromAbstractBaseClassAndReplayOnSubclass() {
256         new Expectations() {
257             {
258                 base.doSomething();
259                 result = 1;
260             }
261         };
262 
263         assertEquals(1, base.doSomething());
264         assertEquals(-1, new SubClass().doSomething());
265     }
266 
267     /**
268      * The Interface BusinessInterface.
269      */
270     public interface BusinessInterface {
271     }
272 
273     /**
274      * Gets the bean info from mocked interface.
275      *
276      * @param mock
277      *            the mock
278      *
279      * @throws Exception
280      *             the exception
281      */
282     @Test
283     void beanInfoFromMockedInterface(@Mocked BusinessInterface mock) throws Exception {
284         Class<? extends BusinessInterface> mockClass = mock.getClass();
285 
286         BeanInfo info = Introspector.getBeanInfo(mockClass);
287 
288         assertNotNull(info);
289     }
290 
291     /**
292      * The Class GenericBase.
293      *
294      * @param <B>
295      *            the generic type
296      */
297     static class GenericBase<B extends Runnable> {
298         /**
299          * Base.
300          *
301          * @return the b
302          */
303         public B base() {
304             return null;
305         }
306     }
307 
308     /**
309      * The Class GenericSubclass.
310      *
311      * @param <S>
312      *            the generic type
313      */
314     public static final class GenericSubclass<S extends Runnable> extends GenericBase<S> {
315         /* bridge method here */ }
316 
317     /**
318      * Record expectation on base method having A synthetic bridge method in subclass.
319      *
320      * @param mock
321      *            the mock
322      */
323     @Test
324     void recordExpectationOnBaseMethodHavingASyntheticBridgeMethodInSubclass(@Mocked final GenericSubclass<?> mock) {
325         new Expectations() {
326             {
327                 mock.base();
328                 result = null;
329             }
330         };
331 
332         assertNull(mock.base());
333     }
334 }