1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.beanutils2;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Modifier;
28
29 import org.apache.commons.beanutils2.priv.PrivateBeanFactory;
30 import org.apache.commons.beanutils2.priv.PublicSubBean;
31 import org.junit.jupiter.api.AfterEach;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38
39
40 public class MethodUtilsTest {
41
42 private static void assertMethod(final Method method, final String methodName) {
43 assertNotNull(method);
44 assertEquals(methodName, method.getName(), "Method is not named correctly");
45 assertTrue(Modifier.isPublic(method.getModifiers()), "Method is not public");
46 }
47
48
49
50
51 @BeforeEach
52 public void setUp() {
53 }
54
55
56
57
58 @AfterEach
59 public void tearDown() {
60 }
61
62
63
64
65 @Test
66 public void testClearCache() throws Exception {
67 MethodUtils.clearCache();
68 final PublicSubBean bean = new PublicSubBean();
69 MethodUtils.invokeMethod(bean, "setFoo", "alpha");
70 assertEquals(1, MethodUtils.clearCache());
71 assertEquals(0, MethodUtils.clearCache());
72 }
73
74
75
76
77
78 @Test
79 public void testGetAccessibleMethod() {
80
81 final Method method = MethodUtils.getAccessibleMethod(TestBean.class, "setStringProperty", String.class);
82
83 assertMethod(method, "setStringProperty");
84 }
85
86 @Test
87 public void testGetAccessibleMethodFromInterface() {
88 Method method;
89
90 method = MethodUtils.getAccessibleMethod(PrivateBeanFactory.create().getClass(), "methodBar", String.class);
91
92 assertMethod(method, "methodBar");
93 }
94
95 @Test
96 public void testGetAccessibleMethodIndirectInterface() {
97 Method method;
98
99 method = MethodUtils.getAccessibleMethod(PrivateBeanFactory.createSubclass().getClass(), "methodBaz", String.class);
100
101 assertMethod(method, "methodBaz");
102 }
103
104
105
106
107
108 @Test
109 public void testInvokeExactMethod() throws Exception {
110 final TestBean bean = new TestBean();
111 final Object ret = MethodUtils.invokeExactMethod(bean, "setStringProperty", "TEST");
112
113 assertNull(ret);
114 assertEquals("TEST", bean.getStringProperty(), "Method ONE was invoked");
115 }
116
117 @Test
118 public void testInvokeExactMethodFromInterface() throws Exception {
119 final Object ret = MethodUtils.invokeExactMethod(PrivateBeanFactory.create(), "methodBar", "ANOTHER TEST");
120
121 assertEquals("ANOTHER TEST", ret, "Method TWO wasn't invoked correctly");
122 }
123
124 @Test
125 public void testInvokeExactMethodIndirectInterface() throws Exception {
126 final Object ret = MethodUtils.invokeExactMethod(PrivateBeanFactory.createSubclass(), "methodBaz", "YET ANOTHER TEST");
127
128 assertEquals("YET ANOTHER TEST", ret, "Method TWO was invoked correctly");
129 }
130
131 @Test
132 public void testInvokeExactMethodNull() throws Exception {
133 final Object object = new Object();
134 final Object result = MethodUtils.invokeExactMethod(object, "toString", (Object) null);
135 assertEquals(object.toString(), result);
136 }
137
138 @Test
139 public void testInvokeExactMethodNullArray() throws Exception {
140 final Object result = MethodUtils.invokeExactMethod(new AlphaBean("parent"), "getName", null);
141 assertEquals("parent", result);
142 }
143
144 @Test
145 public void testInvokeExactMethodNullArrayNullArray() throws Exception {
146 final Object result = MethodUtils.invokeExactMethod(new AlphaBean("parent"), "getName", null, null);
147
148 assertEquals("parent", result);
149 }
150
151 @Test
152 public void testInvokeExactStaticMethodNull() throws Exception {
153 final int current = TestBean.currentCounter();
154 final Object value = MethodUtils.invokeExactStaticMethod(TestBean.class, "currentCounter", (Object) null);
155 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
156 }
157
158
159
160
161
162 @Test
163 public void testInvokeMethod() throws Exception {
164 final AbstractParent parent = new AlphaBean("parent");
165 final BetaBean childOne = new BetaBean("ChildOne");
166
167 assertEquals("ChildOne", MethodUtils.invokeMethod(parent, "testAddChild", childOne), "Cannot invoke through abstract class (1)");
168 }
169
170 @Test
171 public void testInvokeMethodArray() throws Exception {
172 final AbstractParent parent = new AlphaBean("parent");
173 final AlphaBean childTwo = new AlphaBean("ChildTwo");
174
175 final Object[] params = new Object[2];
176 params[0] = "parameter";
177 params[1] = childTwo;
178
179 assertEquals("ChildTwo", MethodUtils.invokeMethod(parent, "testAddChild2", params), "Cannot invoke through abstract class");
180 }
181
182 @Test
183 public void testInvokeMethodNull() throws Exception {
184 final Object object = new Object();
185 final Object result = MethodUtils.invokeMethod(object, "toString", (Object) null);
186 assertEquals(object.toString(), result);
187 }
188
189 @Test
190 public void testInvokeMethodNullArray() throws Exception {
191 final Object result = MethodUtils.invokeMethod(new AlphaBean("parent"), "getName", null);
192
193 assertEquals("parent", result);
194 }
195
196 @Test
197 public void testInvokeMethodNullArrayNullArray() throws Exception {
198 final Object result = MethodUtils.invokeMethod(new AlphaBean("parent"), "getName", null, null);
199
200 assertEquals("parent", result);
201 }
202
203 @Test
204 public void testInvokeMethodObject() throws Exception {
205 final AbstractParent parent = new AlphaBean("parent");
206 final Child childTwo = new AlphaBean("ChildTwo");
207
208 assertEquals("ChildTwo", MethodUtils.invokeMethod(parent, "testAddChild", childTwo), "Cannot invoke through interface (1)");
209 }
210
211 @Test
212 public void testInvokeMethodPrimitiveBoolean() throws Exception {
213 final PrimitiveBean bean = new PrimitiveBean();
214 MethodUtils.invokeMethod(bean, "setBoolean", Boolean.FALSE);
215 assertEquals(false, bean.getBoolean(), "Call boolean property using invokeMethod");
216 }
217
218 @Test
219 public void testInvokeMethodPrimitiveDouble() throws Exception {
220 final PrimitiveBean bean = new PrimitiveBean();
221 MethodUtils.invokeMethod(bean, "setDouble", Double.valueOf(25.5d));
222 assertEquals(25.5d, bean.getDouble(), 0.01d, "Set double property using invokeMethod");
223 }
224
225 @Test
226 public void testInvokeMethodPrimitiveFloat() throws Exception {
227 final PrimitiveBean bean = new PrimitiveBean();
228 MethodUtils.invokeMethod(bean, "setFloat", Float.valueOf(20.0f));
229 assertEquals(20.0f, bean.getFloat(), 0.01f, "Call float property using invokeMethod");
230 }
231
232 @Test
233 public void testInvokeMethodPrimitiveInt() throws Exception {
234 final PrimitiveBean bean = new PrimitiveBean();
235 MethodUtils.invokeMethod(bean, "setInt", Integer.valueOf(12));
236 assertEquals(12, bean.getInt(), "Set int property using invokeMethod");
237 }
238
239 @Test
240 public void testInvokeMethodPrimitiveLong() throws Exception {
241 final PrimitiveBean bean = new PrimitiveBean();
242 MethodUtils.invokeMethod(bean, "setLong", Long.valueOf(10));
243 assertEquals(10, bean.getLong(), "Call long property using invokeMethod");
244 }
245
246 @Test
247 public void testInvokeMethodUnknown() throws Exception {
248
249 final AbstractParent parent = new AlphaBean("parent");
250 final BetaBean childOne = new BetaBean("ChildOne");
251 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(parent, "bogus", childOne));
252 }
253
254 @Test
255 public void testInvokeStaticMethodNull() throws Exception {
256 final int current = TestBean.currentCounter();
257 final Object value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", (Object) null);
258 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
259 }
260
261 @Test
262 public void testNoCaching() throws Exception {
263
264 MethodUtils.setCacheMethods(false);
265
266 final PublicSubBean bean = new PublicSubBean();
267 MethodUtils.invokeMethod(bean, "setFoo", "alpha");
268 assertEquals(0, MethodUtils.clearCache());
269
270
271 MethodUtils.setCacheMethods(true);
272 }
273
274 @Test
275 public void testParentMethod() throws Exception {
276 final String a = "A";
277 final String actual1 = (String) MethodUtils.invokeMethod(a, "toLowerCase", null);
278 assertEquals("a", actual1);
279 final char actual2 = (char) MethodUtils.invokeMethod(a, "charAt", 0);
280 assertEquals('A', actual2);
281 }
282
283 @Test
284 public void testPublicSub() throws Exception {
285
286 final PublicSubBean bean = new PublicSubBean();
287 assertEquals(bean.getFoo(), "This is foo", "Start value (foo)");
288 assertEquals(bean.getBar(), "This is bar", "Start value (bar)");
289 bean.setFoo("new foo");
290 bean.setBar("new bar");
291 assertEquals(bean.getFoo(), "new foo", "Set value (foo)");
292 assertEquals(bean.getBar(), "new bar", "Set value (bar)");
293
294
295
296 MethodUtils.invokeMethod(bean, "setFoo", "alpha");
297 assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)");
298 MethodUtils.invokeMethod(bean, "setBar", "beta");
299 assertEquals(bean.getBar(), "beta", "Set value (bar:2)");
300
301 Method method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class);
302 assertNotNull(method, "getAccessibleMethod() setFoo is Null");
303 method.invoke(bean, "1111");
304 assertEquals("1111", bean.getFoo(), "Set value (foo:3)");
305
306 method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class);
307 assertNotNull(method, "getAccessibleMethod() setBar is Null");
308 method.invoke(bean, "2222");
309 assertEquals("2222", bean.getBar(), "Set value (bar:3)");
310
311 }
312
313
314
315
316 @Test
317 public void testSetCacheMethods() throws Exception {
318 MethodUtils.setCacheMethods(true);
319 MethodUtils.clearCache();
320
321 final PublicSubBean bean = new PublicSubBean();
322 MethodUtils.invokeMethod(bean, "setFoo", "alpha");
323 assertEquals(1, MethodUtils.clearCache());
324 assertEquals(0, MethodUtils.clearCache());
325 }
326
327
328
329
330 @Test
331 public void testSimpleStatic1() throws Exception {
332 final TestBean bean = new TestBean();
333 Object value = null;
334 int current = TestBean.currentCounter();
335
336 value = MethodUtils.invokeMethod(bean, "currentCounter", new Object[0], new Class[0]);
337 assertNotNull(value, "currentCounter exists");
338 assertInstanceOf(Integer.class, value, "currentCounter type");
339 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
340
341
342 MethodUtils.invokeMethod(bean, "incrementCounter", new Object[0], new Class[0]);
343
344
345 current++;
346 value = MethodUtils.invokeMethod(bean, "currentCounter", new Object[0], new Class[0]);
347 assertNotNull(value, "currentCounter exists");
348 assertInstanceOf(Integer.class, value, "currentCounter type");
349 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
350
351
352 MethodUtils.invokeMethod(bean, "incrementCounter", new Object[] { Integer.valueOf(5) }, new Class[] { Integer.TYPE });
353
354
355 current += 5;
356 value = MethodUtils.invokeMethod(bean, "currentCounter", new Object[0], new Class[0]);
357 assertNotNull(value, "currentCounter exists");
358 assertInstanceOf(Integer.class, value, "currentCounter type");
359 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
360 }
361
362
363
364
365 @Test
366 public void testSimpleStatic2() throws Exception {
367 final TestBean bean = new TestBean();
368 Object value = null;
369 int current = TestBean.currentCounter();
370
371 value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]);
372 assertNotNull(value, "currentCounter exists");
373 assertInstanceOf(Integer.class, value, "currentCounter type");
374 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
375
376
377 MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[0], new Class[0]);
378
379
380 current++;
381 value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]);
382 assertNotNull(value, "currentCounter exists");
383 assertInstanceOf(Integer.class, value, "currentCounter type");
384 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
385
386
387 MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[] { Integer.valueOf(5) }, new Class[] { Integer.TYPE });
388
389
390 current += 5;
391 value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]);
392 assertNotNull(value, "currentCounter exists");
393 assertInstanceOf(Integer.class, value, "currentCounter type");
394 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
395 }
396
397
398
399
400 @Test
401 public void testSimpleStatic3() throws Exception {
402 Object value = null;
403 int current = TestBean.currentCounter();
404
405 final Method currentCounterMethod = MethodUtils.getAccessibleMethod(TestBean.class, "currentCounter", new Class[0]);
406 assertNotNull(currentCounterMethod, "currentCounterMethod exists");
407 assertEquals("currentCounter", currentCounterMethod.getName(), "currentCounterMethod name");
408 assertEquals(0, currentCounterMethod.getParameterTypes().length, "currentCounterMethod args");
409 assertTrue(Modifier.isPublic(currentCounterMethod.getModifiers()), "currentCounterMethod public");
410 assertTrue(Modifier.isStatic(currentCounterMethod.getModifiers()), "currentCounterMethod static");
411 final Method incrementCounterMethod1 = MethodUtils.getAccessibleMethod(TestBean.class, "incrementCounter", new Class[0]);
412 assertNotNull(incrementCounterMethod1, "incrementCounterMethod1 exists");
413 assertEquals("incrementCounter", incrementCounterMethod1.getName(), "incrementCounterMethod1 name");
414 assertEquals(0, incrementCounterMethod1.getParameterTypes().length, "incrementCounterMethod1 args");
415 assertTrue(Modifier.isPublic(incrementCounterMethod1.getModifiers()), "incrementCounterMethod1 public");
416 assertTrue(Modifier.isStatic(incrementCounterMethod1.getModifiers()), "incrementCounterMethod1 static");
417 final Method incrementCounterMethod2 = MethodUtils.getAccessibleMethod(TestBean.class, "incrementCounter", new Class[] { Integer.TYPE });
418 assertNotNull(incrementCounterMethod2, "incrementCounterMethod2 exists");
419 assertEquals("incrementCounter", incrementCounterMethod2.getName(), "incrementCounterMethod2 name");
420 assertEquals(1, incrementCounterMethod2.getParameterTypes().length, "incrementCounterMethod2 args");
421 assertTrue(Modifier.isPublic(incrementCounterMethod2.getModifiers()), "incrementCounterMethod2 public");
422 assertTrue(Modifier.isStatic(incrementCounterMethod2.getModifiers()), "incrementCounterMethod2 static");
423
424
425 value = currentCounterMethod.invoke(null);
426 assertNotNull(value, "currentCounter exists");
427 assertInstanceOf(Integer.class, value, "currentCounter type");
428 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
429
430
431 incrementCounterMethod1.invoke(null);
432
433
434 current++;
435 value = currentCounterMethod.invoke(null);
436 assertNotNull(value, "currentCounter exists");
437 assertInstanceOf(Integer.class, value, "currentCounter type");
438 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
439
440
441 incrementCounterMethod2.invoke(null, Integer.valueOf(5));
442
443
444 current += 5;
445 value = currentCounterMethod.invoke(null);
446 assertNotNull(value, "currentCounter exists");
447 assertInstanceOf(Integer.class, value, "currentCounter type");
448 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
449 }
450
451 @Test
452 public void testStaticInvokeMethod() throws Exception {
453
454 Object value;
455 int current = TestBean.currentCounter();
456
457 value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
458 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
459
460 MethodUtils.invokeStaticMethod(TestBean.class, "incrementCounter", new Object[0]);
461 current++;
462
463 value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
464 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
465
466 MethodUtils.invokeStaticMethod(TestBean.class, "incrementCounter", new Object[] { Integer.valueOf(8) });
467 current += 8;
468
469 value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
470 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
471
472 MethodUtils.invokeExactStaticMethod(TestBean.class, "incrementCounter", new Object[] { Integer.valueOf(8) }, new Class[] { Number.class });
473 current += 16;
474
475 value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
476 assertEquals(current, ((Integer) value).intValue(), "currentCounter value");
477 }
478 }