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.assertSame;
10  
11  import jakarta.servlet.Servlet;
12  import jakarta.servlet.ServletConfig;
13  import jakarta.servlet.ServletRequest;
14  import jakarta.servlet.ServletResponse;
15  
16  import java.net.InetAddress;
17  import java.net.UnknownHostException;
18  
19  import mockit.integration.junit5.JMockitExtension;
20  
21  import org.junit.jupiter.api.AfterEach;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Disabled;
24  import org.junit.jupiter.api.Test;
25  import org.junit.jupiter.api.extension.ExtendWith;
26  
27  /**
28   * The Class TestedClassWithConstructorDI2Test.
29   */
30  // TODO JWL 2/18/2024 Mocking InetAddress is not allowed on JDK9+ because java.net classes reside in a restricted JDK
31  // module that the JVM does not allow to be modified. To test code that depends on InetAddress, consider wrapping
32  // network operations behind a testable interface or abstraction that can be mocked instead.
33  @Disabled
34  @ExtendWith(JMockitExtension.class)
35  final class TestedClassWithConstructorDI2Test {
36  
37      /**
38       * The Class TestedClass.
39       */
40      public static final class TestedClass implements Servlet {
41  
42          /** The counter. */
43          static int counter;
44  
45          /** The config. */
46          private ServletConfig config;
47  
48          /** The dependency 1. */
49          private final Dependency dependency1;
50  
51          /** The dependency 2. */
52          private final Dependency dependency2;
53  
54          /** The dependency 3. */
55          private final Dependency dependency3;
56  
57          /**
58           * Instantiates a new tested class.
59           *
60           * @param dependency1
61           *            the dependency 1
62           * @param r
63           *            the r
64           * @param dependency2
65           *            the dependency 2
66           * @param dependency3
67           *            the dependency 3
68           */
69          public TestedClass(Dependency dependency1, Runnable r, Dependency dependency2, Dependency dependency3) {
70              this.dependency1 = dependency1;
71              this.dependency2 = dependency2;
72              this.dependency3 = dependency3;
73              r.run();
74  
75              int i = dependency1.doSomething();
76              assert i == 123;
77  
78              try {
79                  InetAddress localHost = InetAddress.getLocalHost();
80                  assert localHost.getHostName() == null;
81              } catch (UnknownHostException e) {
82                  throw new IllegalStateException("InetAddress should be mocked", e);
83              }
84          }
85  
86          /**
87           * Do some operation.
88           *
89           * @return the int
90           */
91          public int doSomeOperation() {
92              return dependency1.doSomething() + dependency2.doSomething();
93          }
94  
95          @Override
96          public ServletConfig getServletConfig() {
97              return config;
98          }
99  
100         @Override
101         public void service(ServletRequest req, ServletResponse res) {
102         }
103 
104         @Override
105         public String getServletInfo() {
106             return null;
107         }
108 
109         @Override
110         public void init(ServletConfig cfg) {
111             config = cfg;
112             counter++;
113 
114             int i = dependency1.doSomething();
115             assert i == 123;
116 
117             checkInetAddressMocking();
118         }
119 
120         /**
121          * Check inet address mocking.
122          */
123         private void checkInetAddressMocking() {
124             try {
125                 InetAddress inetAddress = InetAddress.getByName("testHost");
126                 assert inetAddress.getHostName() == null;
127             } catch (UnknownHostException ignore) {
128                 counter = -1;
129             }
130         }
131 
132         @Override
133         public void destroy() {
134             counter++;
135             checkInetAddressMocking();
136         }
137     }
138 
139     /**
140      * The Class Dependency.
141      */
142     static class Dependency {
143         /**
144          * Do something.
145          *
146          * @return the int
147          */
148         int doSomething() {
149             return -1;
150         }
151     }
152 
153     /** The tested. */
154     @Tested
155     TestedClass tested;
156 
157     /** The task. */
158     @Injectable
159     Runnable task;
160 
161     /** The dependency 1. */
162     @Injectable
163     Dependency dependency1;
164 
165     /** The dependency 2. */
166     @Injectable
167     Dependency dependency2;
168 
169     /** The config. */
170     @Injectable
171     ServletConfig config;
172 
173     /** The test host. */
174     @Mocked
175     InetAddress testHost;
176 
177     /**
178      * Reset counter.
179      */
180     @BeforeEach
181     void resetCounter() {
182         TestedClass.counter = 0;
183         new Expectations() {
184             {
185                 dependency1.doSomething();
186                 result = 123;
187             }
188         };
189     }
190 
191     /**
192      * Exercise tested object with dependencies of same type injected through constructor.
193      *
194      * @param dependency3
195      *            the dependency 3
196      */
197     @Test
198     void exerciseTestedObjectWithDependenciesOfSameTypeInjectedThroughConstructor(@Injectable Dependency dependency3) {
199         assertTestedObjectWasInitialized();
200         assertSame(dependency3, tested.dependency3);
201 
202         new Expectations() {
203             {
204                 dependency1.doSomething();
205                 result = 23;
206                 dependency2.doSomething();
207                 result = 5;
208             }
209         };
210 
211         assertEquals(28, tested.doSomeOperation());
212     }
213 
214     /**
215      * Exercise tested object with extra injectable parameter.
216      *
217      * @param dependency3
218      *            the dependency 3
219      * @param mock4
220      *            the mock 4
221      */
222     @Test
223     void exerciseTestedObjectWithExtraInjectableParameter(@Injectable Dependency dependency3,
224             @Injectable Dependency mock4) {
225         assertTestedObjectWasInitialized();
226         assertSame(dependency1, tested.dependency1);
227         assertSame(dependency2, tested.dependency2);
228         assertSame(dependency3, tested.dependency3);
229     }
230 
231     /**
232      * Assert tested object was initialized.
233      */
234     void assertTestedObjectWasInitialized() {
235         assertSame(config, tested.getServletConfig());
236         assertEquals(1, TestedClass.counter);
237     }
238 
239     /**
240      * Verify tested object after every test.
241      */
242     @AfterEach
243     void verifyTestedObjectAfterEveryTest() {
244         assertEquals(2, TestedClass.counter);
245     }
246 }