1
2
3
4
5 package mockit;
6
7 import static org.junit.jupiter.api.Assertions.assertEquals;
8 import static org.junit.jupiter.api.Assertions.assertTrue;
9 import static org.junit.jupiter.api.Assertions.fail;
10
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.List;
14
15 import org.junit.jupiter.api.Test;
16
17 public final class MockUpForGenericsTest {
18
19
20 public static final class Collaborator {
21 public <N extends Number> N genericMethod(@SuppressWarnings("UnusedParameters") N n) {
22 return null;
23 }
24 }
25
26 @Test
27 public void mockGenericMethod() {
28 new MockUp<Collaborator>() {
29 @Mock
30 <T extends Number> T genericMethod(T t) {
31 return t;
32 }
33
34
35
36 };
37
38 Integer n = new Collaborator().genericMethod(123);
39 assertEquals(123, n.intValue());
40
41 Long l = new Collaborator().genericMethod(45L);
42 assertEquals(45L, l.longValue());
43
44 Short s = new Collaborator().genericMethod((short) 6);
45 assertEquals(6, s.shortValue());
46
47 Double d = new Collaborator().genericMethod(0.5);
48 assertEquals(0.5, d, 0);
49 }
50
51 @SuppressWarnings("UnusedParameters")
52 public static final class GenericClass<T1, T2> {
53 public void aMethod(T1 t) {
54 throw new RuntimeException("t=" + t);
55 }
56
57 public int anotherMethod(T1 t, int i, T2 p) {
58 return 2 * i;
59 }
60
61 public int anotherMethod(Integer t, int i, String p) {
62 return -2 * i;
63 }
64 }
65
66 @Test
67 public void mockGenericClassWithUnspecifiedTypeArguments() {
68 new MockUp<GenericClass<?, ?>>() {
69 @Mock
70 void aMethod(Object o) {
71 StringBuilder s = (StringBuilder) o;
72 s.setLength(0);
73 s.append("mock");
74 s.toString();
75 }
76
77 @Mock
78 int anotherMethod(Object o, int i, Object list) {
79 assertTrue(o instanceof StringBuilder);
80
81 assertEquals(0, ((Collection<String>) list).size());
82 return -i;
83 }
84 };
85
86 StringBuilder s = new StringBuilder("test");
87 GenericClass<StringBuilder, List<String>> g = new GenericClass<>();
88
89 g.aMethod(s);
90 int r1 = g.anotherMethod(new StringBuilder("test"), 58, Collections.<String> emptyList());
91 int r2 = g.anotherMethod(123, 65, "abc");
92
93 assertEquals("mock", s.toString());
94 assertEquals(-58, r1);
95 assertEquals(-130, r2);
96 }
97
98 @Test
99 public void mockBothGenericAndNonGenericMethodsInGenericClass() {
100 new MockUp<GenericClass<String, Boolean>>() {
101 @Mock
102 int anotherMethod(Integer t, int i, String p) {
103 return 2;
104 }
105
106 @Mock
107 int anotherMethod(String t, int i, Boolean p) {
108 return 1;
109 }
110 };
111
112 GenericClass<String, Boolean> o = new GenericClass<>();
113 assertEquals(1, o.anotherMethod("generic", 1, true));
114 assertEquals(2, o.anotherMethod(123, 2, "non generic"));
115 }
116
117 static class GenericBaseClass<T, U> {
118 public U find(@SuppressWarnings("UnusedParameters") T id) {
119 return null;
120 }
121 }
122
123 @Test
124 public void mockGenericMethodWithMockMethodHavingParameterTypesMatchingTypeArguments() {
125 new MockUp<GenericBaseClass<String, Integer>>() {
126 @Mock
127 Integer find(String id) {
128 return id.hashCode();
129 }
130 };
131
132 int i = new GenericBaseClass<String, Integer>().find("test");
133 assertEquals("test".hashCode(), i);
134 }
135
136 @Test
137 public void cannotCallGenericMethodWhenSomeMockMethodExpectsDifferentTypes() {
138 new MockUp<GenericBaseClass<String, Integer>>() {
139 @Mock
140 Integer find(String id) {
141 return 1;
142 }
143 };
144
145 try {
146 new GenericBaseClass<Integer, String>().find(1);
147 fail();
148 } catch (IllegalArgumentException e) {
149 assertTrue(e.getMessage().startsWith("Failure to invoke method: "));
150 }
151 }
152
153 static class NonGenericSuperclass extends GenericBaseClass<Integer, String> {
154 }
155
156 final class NonGenericSubclass extends NonGenericSuperclass {
157 }
158
159 @Test
160 public void mockGenericMethodFromInstantiationOfNonGenericSubclass() {
161 new MockUp<NonGenericSubclass>() {
162 @Mock
163 String find(Integer id) {
164 return "mocked" + id;
165 }
166 };
167
168 String s = new NonGenericSubclass().find(1);
169 assertEquals("mocked1", s);
170 }
171
172 static class GenericSuperclass<I> extends GenericBaseClass<I, String> {
173 }
174
175 final class AnotherNonGenericSubclass extends GenericSuperclass<Integer> {
176 }
177
178 @Test
179 public void mockGenericMethodFromInstantiationOfNonGenericSubclassWhichExtendsAGenericIntermediateSuperclass() {
180 new MockUp<AnotherNonGenericSubclass>() {
181 @Mock
182 String find(Integer id) {
183 return "mocked" + id;
184 }
185 };
186
187 String s = new AnotherNonGenericSubclass().find(1);
188 assertEquals("mocked1", s);
189 }
190
191 @SuppressWarnings("UnusedParameters")
192 public static class NonGenericClassWithGenericMethods {
193 public static <T> T staticMethod(Class<T> cls, String s) {
194 throw new RuntimeException();
195 }
196
197 public <C> void instanceMethod(Class<C> cls, String s) {
198 throw new RuntimeException();
199 }
200
201 public final <N extends Number> void instanceMethod(Class<N> cls) {
202 throw new RuntimeException();
203 }
204 }
205
206 @Test
207 public void mockGenericMethodsOfNonGenericClass() {
208 new MockUp<NonGenericClassWithGenericMethods>() {
209 @Mock
210 <T> T staticMethod(Class<T> cls, String s) {
211 return null;
212 }
213
214 @Mock
215 <C> void instanceMethod(Class<C> cls, String s) {
216 }
217
218 @Mock
219 void instanceMethod(Class<?> cls) {
220 }
221 };
222
223 new NonGenericClassWithGenericMethods().instanceMethod(Integer.class);
224 NonGenericClassWithGenericMethods.staticMethod(Collaborator.class, "test1");
225 new NonGenericClassWithGenericMethods().instanceMethod(Byte.class, "test2");
226 }
227
228
229
230 public interface GenericInterface<T> {
231 void method(T t);
232 }
233
234 @Test
235 public void mockGenericInterfaceMethodWithMockMethodHavingParameterOfTypeObject() {
236 GenericInterface<Boolean> mock = new MockUp<GenericInterface<Boolean>>() {
237 @Mock
238 void method(Object b) {
239 assertTrue((Boolean) b);
240 }
241 }.getMockInstance();
242
243 mock.method(true);
244 }
245
246 public interface NonGenericSubInterface extends GenericInterface<Long> {
247 }
248
249 @Test
250 public void mockMethodOfSubInterfaceWithGenericTypeArgument() {
251 NonGenericSubInterface mock = new MockUp<NonGenericSubInterface>() {
252 @Mock
253 void method(Long l) {
254 assertTrue(l > 0);
255 }
256 }.getMockInstance();
257
258 mock.method(123L);
259 }
260
261 @Test
262 public void mockGenericInterfaceMethod() {
263 Comparable<Integer> cmp = new MockUp<Comparable<Integer>>() {
264 @Mock
265 int compareTo(Integer i) {
266 assertEquals(123, i.intValue());
267 return 2;
268 }
269 }.getMockInstance();
270
271 assertEquals(2, cmp.compareTo(123));
272 }
273 }