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.assertTrue;
10  
11  import jakarta.annotation.PostConstruct;
12  import jakarta.annotation.PreDestroy;
13  
14  import java.util.Observable;
15  
16  import mockit.integration.junit5.JMockitExtension;
17  
18  import org.junit.jupiter.api.AfterEach;
19  import org.junit.jupiter.api.BeforeEach;
20  import org.junit.jupiter.api.Test;
21  import org.junit.jupiter.api.extension.ExtendWith;
22  
23  /**
24   * The Class TestedClassWithConstructorDI1Test.
25   */
26  @ExtendWith(JMockitExtension.class)
27  class TestedClassWithConstructorDI1Test {
28  
29      /**
30       * The Class BaseTestedClass.
31       */
32      public static class BaseTestedClass {
33  
34          /** The base counter. */
35          static int baseCounter;
36  
37          /**
38           * Initialize base.
39           */
40          @PostConstruct
41          void initializeBase() {
42              baseCounter++;
43          }
44  
45          /**
46           * Destroy base.
47           */
48          @PreDestroy
49          void destroyBase() {
50              baseCounter++;
51          }
52      }
53  
54      /**
55       * The Class TestedClass.
56       */
57      public static final class TestedClass extends BaseTestedClass {
58  
59          /** The counter. */
60          static int counter;
61  
62          /** The dependency. */
63          private final Dependency dependency;
64  
65          /** The runnable. */
66          private final Runnable runnable;
67  
68          /** The observable. */
69          private final Observable observable;
70  
71          /**
72           * Instantiates a new tested class.
73           *
74           * @param dependency
75           *            the dependency
76           */
77          public TestedClass(Dependency dependency) {
78              this(dependency, null, null);
79          }
80  
81          /**
82           * Instantiates a new tested class.
83           *
84           * @param dependency
85           *            the dependency
86           * @param runnable
87           *            the runnable
88           */
89          public TestedClass(Dependency dependency, Runnable runnable) {
90              this(dependency, runnable, null);
91          }
92  
93          /**
94           * Instantiates a new tested class.
95           *
96           * @param dependency
97           *            the dependency
98           * @param observable
99           *            the observable
100          */
101         public TestedClass(Dependency dependency, Observable observable) {
102             this(dependency, null, observable);
103         }
104 
105         /**
106          * Instantiates a new tested class.
107          *
108          * @param dependency
109          *            the dependency
110          * @param runnable
111          *            the runnable
112          * @param observable
113          *            the observable
114          */
115         public TestedClass(Dependency dependency, Runnable runnable, Observable observable) {
116             this.dependency = dependency;
117             this.runnable = runnable;
118             this.observable = observable;
119         }
120 
121         /**
122          * Do some operation.
123          *
124          * @return true, if successful
125          */
126         public boolean doSomeOperation() {
127             if (runnable != null) {
128                 runnable.run();
129             }
130 
131             boolean b = dependency.doSomething() > 0;
132 
133             if (b && observable != null) {
134                 observable.notifyObservers();
135             }
136 
137             return b;
138         }
139 
140         /**
141          * Initialize.
142          */
143         @PostConstruct
144         void initialize() {
145             counter++;
146         }
147 
148         /**
149          * Destroy.
150          */
151         @PreDestroy
152         void destroy() {
153             counter++;
154         }
155     }
156 
157     /**
158      * The Class Dependency.
159      */
160     static class Dependency {
161         /**
162          * Do something.
163          *
164          * @return the int
165          */
166         int doSomething() {
167             return -1;
168         }
169     }
170 
171     /** The tested. */
172     @Tested
173     TestedClass tested;
174 
175     /** The mock. */
176     @Injectable
177     Dependency mock;
178 
179     /**
180      * Exercise tested object with single dependency injected through constructor.
181      */
182     @Test
183     void exerciseTestedObjectWithSingleDependencyInjectedThroughConstructor() {
184         assertTestedObjectWasInitialized();
185 
186         new Expectations() {
187             {
188                 mock.doSomething();
189                 result = 23;
190             }
191         };
192 
193         assertTrue(tested.doSomeOperation());
194     }
195 
196     /**
197      * Exercise tested object with two dependencies injected through constructor.
198      *
199      * @param mock2
200      *            the mock 2
201      */
202     @Test
203     void exerciseTestedObjectWithTwoDependenciesInjectedThroughConstructor(@Injectable final Runnable mock2) {
204         assertTestedObjectWasInitialized();
205 
206         new Expectations() {
207             {
208                 mock.doSomething();
209                 result = 23;
210             }
211         };
212 
213         assertTrue(tested.doSomeOperation());
214 
215         new Verifications() {
216             {
217                 mock2.run();
218             }
219         };
220     }
221 
222     /**
223      * Exercise tested object with two other dependencies injected through constructor.
224      *
225      * @param obs
226      *            the obs
227      */
228     @Test
229     void exerciseTestedObjectWithTwoOtherDependenciesInjectedThroughConstructor(@Injectable final Observable obs) {
230         assertTestedObjectWasInitialized();
231 
232         new Expectations() {
233             {
234                 mock.doSomething();
235                 result = 123;
236             }
237         };
238 
239         assertTrue(tested.doSomeOperation());
240 
241         new FullVerifications() {
242             {
243                 obs.notifyObservers();
244             }
245         };
246     }
247 
248     /**
249      * Exercise tested object with all dependencies injected through constructor.
250      *
251      * @param mock2
252      *            the mock 2
253      * @param mock3
254      *            the mock 3
255      */
256     @Test
257     void exerciseTestedObjectWithAllDependenciesInjectedThroughConstructor(@Injectable final Runnable mock2,
258             @Injectable final Observable mock3) {
259         assertTestedObjectWasInitialized();
260 
261         new Expectations() {
262             {
263                 mock.doSomething();
264                 result = 123;
265             }
266         };
267 
268         assertTrue(tested.doSomeOperation());
269 
270         new VerificationsInOrder() {
271             {
272                 mock2.run();
273                 mock3.notifyObservers();
274             }
275         };
276     }
277 
278     /**
279      * Reset counter.
280      */
281     @BeforeEach
282     void resetCounter() {
283         BaseTestedClass.baseCounter = 0;
284         TestedClass.counter = 0;
285     }
286 
287     /**
288      * Assert tested object was initialized.
289      */
290     void assertTestedObjectWasInitialized() {
291         assertEquals(1, BaseTestedClass.baseCounter);
292         assertEquals(1, TestedClass.counter);
293     }
294 
295     /**
296      * Verify tested object after every test.
297      */
298     @AfterEach
299     void verifyTestedObjectAfterEveryTest() {
300         assertEquals(2, BaseTestedClass.baseCounter);
301         assertEquals(2, TestedClass.counter);
302     }
303 }