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.assertNotSame;
10  import static org.junit.jupiter.api.Assertions.assertSame;
11  
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import org.junit.jupiter.api.Test;
16  import org.junit.jupiter.api.Timeout;
17  import org.slf4j.Logger;
18  import org.slf4j.LoggerFactory;
19  
20  class MockUpForSingleInterfaceInstanceTest {
21  
22      /** The logger. */
23      private static final Logger logger = LoggerFactory.getLogger(MockUpForSingleInterfaceInstanceTest.class);
24  
25      public interface APublicInterface {
26          int getNumericValue();
27  
28          String getTextValue();
29  
30          int getSomeOtherValue();
31      }
32  
33      @Test
34      void multipleMockUpInstancesForAPublicInterfaceWithASingleMockInstanceEach() {
35          final class AnInterfaceMockUp extends MockUp<APublicInterface> {
36              private final int number;
37              private final String text;
38  
39              AnInterfaceMockUp(int number, String text) {
40                  this.number = number;
41                  this.text = text;
42              }
43  
44              @Mock
45              int getNumericValue() {
46                  return number;
47              }
48  
49              @Mock
50              String getTextValue() {
51                  return text;
52              }
53          }
54  
55          MockUp<APublicInterface> mockUp1 = new AnInterfaceMockUp(1, "one");
56          APublicInterface mock1 = mockUp1.getMockInstance();
57  
58          AnInterfaceMockUp mockUp2 = new AnInterfaceMockUp(2, "two");
59          APublicInterface mock2 = mockUp2.getMockInstance();
60  
61          assertNotSame(mock1, mock2);
62          assertSame(mock1.getClass(), mock2.getClass());
63          assertEquals(1, mock1.getNumericValue());
64          assertEquals("one", mock1.getTextValue());
65          // TODO 12/12/2023 yukkes The FieldInjection class has changed and the default value is not set.
66          // assertEquals(0, mock1.getSomeOtherValue());
67          assertEquals(2, mock2.getNumericValue());
68          assertEquals("two", mock2.getTextValue());
69          // assertEquals(0, mock2.getSomeOtherValue());
70      }
71  
72      @Test
73      void multipleMockUpInstancesForPublicInterfacePassingInterfaceToMockUpConstructor() {
74          final class AnInterfaceMockUp extends MockUp<APublicInterface> {
75              private final int number;
76  
77              AnInterfaceMockUp(int number) {
78                  super(APublicInterface.class);
79                  this.number = number;
80              }
81  
82              @Mock
83              int getNumericValue() {
84                  return number;
85              }
86          }
87  
88          MockUp<APublicInterface> mockUp1 = new AnInterfaceMockUp(1);
89          APublicInterface mock1 = mockUp1.getMockInstance();
90  
91          AnInterfaceMockUp mockUp2 = new AnInterfaceMockUp(2);
92          APublicInterface mock2 = mockUp2.getMockInstance();
93  
94          assertNotSame(mock1, mock2);
95          assertSame(mock1.getClass(), mock2.getClass());
96          assertEquals(1, mock1.getNumericValue());
97          assertEquals(2, mock2.getNumericValue());
98      }
99  
100     @Test
101     @Timeout(500)
102     @SuppressWarnings("MethodWithMultipleLoops")
103     void instantiateSameMockUpForPublicInterfaceManyTimesButApplyOnlyOnce() {
104         class InterfaceMockUp extends MockUp<APublicInterface> {
105             final int value;
106 
107             InterfaceMockUp(int value) {
108                 this.value = value;
109             }
110 
111             @Mock
112             int getNumericValue() {
113                 return value;
114             }
115         }
116 
117         int n = 10000;
118         List<APublicInterface> mocks = new ArrayList<>(n);
119         Class<?> implementationClass = null;
120 
121         for (int i = 0; i < n; i++) {
122             if (Thread.interrupted()) {
123                 logger.info("a) Interrupted at i = {}", i);
124                 return;
125             }
126 
127             APublicInterface mockInstance = new InterfaceMockUp(i).getMockInstance();
128             Class<?> mockInstanceClass = mockInstance.getClass();
129 
130             if (implementationClass == null) {
131                 implementationClass = mockInstanceClass;
132             } else {
133                 assertSame(implementationClass, mockInstanceClass);
134             }
135 
136             mocks.add(mockInstance);
137         }
138 
139         for (int i = 0; i < n; i++) {
140             if (Thread.interrupted()) {
141                 logger.info("b) Interrupted at i = {}", i);
142                 return;
143             }
144 
145             APublicInterface mockInstance = mocks.get(i);
146             assertEquals(i, mockInstance.getNumericValue());
147         }
148     }
149 
150     interface ANonPublicInterface {
151         int getValue();
152     }
153 
154     @Test
155     void multipleMockUpInstancesForANonPublicInterfaceWithASingleMockInstanceEach() {
156         class AnotherInterfaceMockUp extends MockUp<ANonPublicInterface> implements ANonPublicInterface {
157             private final int value;
158 
159             AnotherInterfaceMockUp(int value) {
160                 this.value = value;
161             }
162 
163             @Override
164             @Mock
165             public int getValue() {
166                 return value;
167             }
168         }
169 
170         MockUp<ANonPublicInterface> mockUp1 = new AnotherInterfaceMockUp(1);
171         ANonPublicInterface mock1 = mockUp1.getMockInstance();
172 
173         AnotherInterfaceMockUp mockUp2 = new AnotherInterfaceMockUp(2);
174         ANonPublicInterface mock2 = mockUp2.getMockInstance();
175 
176         assertNotSame(mock1, mock2);
177         assertSame(mock1.getClass(), mock2.getClass());
178         assertEquals(1, mock1.getValue());
179         assertEquals(2, mock2.getValue());
180     }
181 
182     @Test
183     void applyDifferentMockUpsToSameInterface() {
184         APublicInterface mock1 = new MockUp<APublicInterface>() {
185             @Mock
186             String getTextValue() {
187                 return "test";
188             }
189         }.getMockInstance();
190 
191         APublicInterface mock2 = new MockUp<APublicInterface>() {
192             @Mock
193             int getNumericValue() {
194                 return 123;
195             }
196         }.getMockInstance();
197 
198         assertEquals("test", mock1.getTextValue());
199         // TODO 12/12/2023 yukkes The FieldInjection class has changed and the default value is not set.
200         // assertEquals(0, mock1.getNumericValue());
201         assertEquals(123, mock2.getNumericValue());
202         // assertNull(mock2.getTextValue());
203     }
204 
205     @Test
206     void applyMockUpWithGivenInterfaceInstance() {
207         APublicInterface realInstance = new APublicInterface() {
208             @Override
209             public int getNumericValue() {
210                 return 1;
211             }
212 
213             @Override
214             public String getTextValue() {
215                 return "test";
216             }
217 
218             @Override
219             public int getSomeOtherValue() {
220                 return 2;
221             }
222         };
223 
224         MockUp<APublicInterface> mockUp = new MockUp<APublicInterface>(realInstance) {
225             @Mock
226             int getNumericValue() {
227                 return 3;
228             }
229         };
230 
231         APublicInterface mockInstance = mockUp.getMockInstance();
232         assertSame(realInstance, mockInstance);
233 
234         assertEquals(2, realInstance.getSomeOtherValue());
235         assertEquals(3, mockInstance.getNumericValue());
236     }
237 }