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.assertFalse;
9   import static org.junit.jupiter.api.Assertions.assertTrue;
10  
11  import java.util.Observable;
12  import java.util.Observer;
13  import java.util.concurrent.Callable;
14  
15  import mockit.integration.junit5.JMockitExtension;
16  
17  import org.junit.jupiter.api.Test;
18  import org.junit.jupiter.api.extension.ExtendWith;
19  
20  /**
21   * The Class MultipleMockedTypesTest.
22   */
23  @ExtendWith(JMockitExtension.class)
24  class MultipleMockedTypesTest {
25  
26      /**
27       * The Class FirstDependency.
28       */
29      public static class FirstDependency {
30          /**
31           * Gets the value.
32           *
33           * @return the value
34           */
35          public int getValue() {
36              return 1;
37          }
38      }
39  
40      /**
41       * The Class SecondDependency.
42       */
43      public static class SecondDependency {
44  
45          /**
46           * Gets the value.
47           *
48           * @return the value
49           */
50          public int getValue() {
51              return 2;
52          }
53  
54          /**
55           * Gets the different value.
56           *
57           * @return the different value
58           */
59          public int getDifferentValue() {
60              return 3;
61          }
62      }
63  
64      /**
65       * The Class TestedUnit.
66       */
67      public static class TestedUnit {
68  
69          /**
70           * Validate.
71           *
72           * @param first
73           *            the first
74           *
75           * @return true, if successful
76           */
77          public boolean validate(FirstDependency first) {
78              SecondDependency second = new SecondDependency();
79              return first.getValue() + second.getValue() <= 0;
80          }
81  
82          /**
83           * Validate with different value.
84           *
85           * @param first
86           *            the first
87           *
88           * @return true, if successful
89           */
90          public boolean validateWithDifferentValue(FirstDependency first) {
91              SecondDependency second = new SecondDependency();
92              return first.getValue() + second.getDifferentValue() <= 0;
93          }
94  
95          /**
96           * Validate.
97           *
98           * @param first
99           *            the first
100          * @param second
101          *            the second
102          *
103          * @return true, if successful
104          */
105         public boolean validate(FirstDependency first, SecondDependency second) {
106             return first.getValue() + second.getValue() <= 0;
107         }
108 
109         /**
110          * Do something with internally created implementations.
111          */
112         static void doSomethingWithInternallyCreatedImplementations() {
113             new Observer() {
114                 @Override
115                 public void update(Observable o, Object arg) {
116                     throw new IllegalStateException();
117                 }
118             }.update(null, "event");
119 
120             new Callable<String>() {
121                 @Override
122                 public String call() {
123                     return "tested";
124                 }
125             }.call();
126         }
127     }
128 
129     /** The mock 1. */
130     @Mocked
131     FirstDependency mock1;
132 
133     /**
134      * Invocations on methods of different classes with different signatures.
135      *
136      * @param mock2
137      *            the mock 2
138      */
139     @Test
140     void invocationsOnMethodsOfDifferentClassesWithDifferentSignatures(@Mocked final SecondDependency mock2) {
141         new Expectations() {
142             {
143                 mock1.getValue();
144                 result = 15;
145                 mock2.getDifferentValue();
146                 result = -50;
147             }
148         };
149 
150         assertTrue(new TestedUnit().validateWithDifferentValue(mock1));
151     }
152 
153     /**
154      * Invocations on methods of different classes but same signature.
155      *
156      * @param mock2
157      *            the mock 2
158      */
159     @Test
160     void invocationsOnMethodsOfDifferentClassesButSameSignature(@Mocked final SecondDependency mock2) {
161         new Expectations() {
162             {
163                 mock1.getValue();
164                 result = 15;
165                 mock2.getValue();
166                 result = -50;
167             }
168         };
169 
170         assertTrue(new TestedUnit().validate(mock1));
171 
172         new VerificationsInOrder() {
173             {
174                 mock1.getValue();
175                 mock2.getValue();
176             }
177         };
178     }
179 
180     /**
181      * The Class SubDependencyThatInherits.
182      */
183     public static final class SubDependencyThatInherits extends SecondDependency {
184     }
185 
186     /**
187      * The Class SubDependencyThatOverrides.
188      */
189     public static final class SubDependencyThatOverrides extends SecondDependency {
190         @Override
191         public int getValue() {
192             return 1;
193         }
194     }
195 
196     /**
197      * Invocation on base type with replay on subtype that overrides the invoked method.
198      *
199      * @param mock2
200      *            the mock 2
201      */
202     @Test
203     void invocationOnBaseTypeWithReplayOnSubtypeThatOverridesTheInvokedMethod(@Mocked final SecondDependency mock2) {
204         new Expectations() {
205             {
206                 mock1.getValue();
207                 result = 15;
208             }
209         };
210 
211         // The executed method will be the override, which is not mocked.
212         assertFalse(new TestedUnit().validate(mock1, new SubDependencyThatOverrides()));
213 
214         new FullVerifications() {
215             {
216                 mock2.getValue();
217                 times = 0;
218             }
219         };
220     }
221 
222     /**
223      * Invocation on base type with capturing of subtype that inherits the invoked method.
224      *
225      * @param mock2
226      *            the mock 2
227      */
228     @Test
229     void invocationOnBaseTypeWithCapturingOfSubtypeThatInheritsTheInvokedMethod(
230             @Capturing final SecondDependency mock2) {
231         new Expectations() {
232             {
233                 mock1.getValue();
234                 result = 15;
235                 mock2.getValue();
236                 result = -50;
237             }
238         };
239 
240         assertTrue(new TestedUnit().validate(mock1, new SubDependencyThatInherits()));
241     }
242 
243     /**
244      * Invocation on base type with capturing of subtype that overrides the invoked method.
245      *
246      * @param mock2
247      *            the mock 2
248      */
249     @Test
250     void invocationOnBaseTypeWithCapturingOfSubtypeThatOverridesTheInvokedMethod(
251             @Capturing final SecondDependency mock2) {
252         new Expectations() {
253             {
254                 mock1.getValue();
255                 result = 15;
256                 mock2.getValue();
257                 result = -50;
258             }
259         };
260 
261         assertTrue(new TestedUnit().validate(mock1, new SubDependencyThatOverrides()));
262 
263         new VerificationsInOrder() {
264             {
265                 mock1.getValue();
266                 mock2.getValue();
267             }
268         };
269     }
270 
271     /**
272      * Invocations on captured implementations of interfaces.
273      *
274      * @param callable
275      *            the callable
276      * @param observer
277      *            the observer
278      *
279      * @throws Exception
280      *             the exception
281      */
282     @Test
283     void invocationsOnCapturedImplementationsOfInterfaces(@Capturing final Callable<String> callable,
284             @Capturing final Observer observer) throws Exception {
285         new Expectations() {
286             {
287                 observer.update(null, any);
288                 times = 1;
289             }
290         };
291 
292         TestedUnit.doSomethingWithInternallyCreatedImplementations();
293 
294         new Verifications() {
295             {
296                 callable.call();
297             }
298         };
299     }
300 }