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