blob: 59a59840e53ee1618bfaac32fd4a655917078527 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang.reflect;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.mutable.Mutable;
import org.apache.commons.lang.mutable.MutableObject;
/**
* Unit tests MethodUtils
* @author mbenson
* @version $Id$
*/
public class MethodUtilsTest extends TestCase {
public static class TestBean {
public static String bar() {
return "bar()";
}
public static String bar(int i) {
return "bar(int)";
}
public static String bar(Integer i) {
return "bar(Integer)";
}
public static String bar(double d) {
return "bar(double)";
}
public static String bar(String s) {
return "bar(String)";
}
public static String bar(Object o) {
return "bar(Object)";
}
public String foo() {
return "foo()";
}
public String foo(int i) {
return "foo(int)";
}
public String foo(Integer i) {
return "foo(Integer)";
}
public String foo(double d) {
return "foo(double)";
}
public String foo(String s) {
return "foo(String)";
}
public String foo(Object o) {
return "foo(Object)";
}
}
private static class TestMutable implements Mutable {
public Object getValue() {
return null;
}
public void setValue(Object value) {
}
}
private TestBean testBean;
private Map classCache;
public MethodUtilsTest(String name) {
super(name);
classCache = new HashMap();
}
/**
* Run the test cases as a suite.
* @return the Test
*/
public static Test suite() {
TestSuite suite = new TestSuite(MethodUtilsTest.class);
suite.setName("MethodUtils Tests");
return suite;
}
protected void setUp() throws Exception {
super.setUp();
testBean = new TestBean();
classCache.clear();
}
public void testConstructor() throws Exception {
assertNotNull(MethodUtils.class.newInstance());
}
public void testInvokeMethod() throws Exception {
assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo",
ArrayUtils.EMPTY_CLASS_ARRAY));
assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo",
(Class[]) null));
assertEquals("foo(String)", MethodUtils.invokeMethod(testBean, "foo",
""));
assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo",
new Object()));
assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo",
Boolean.TRUE));
assertEquals("foo(Integer)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.INTEGER_ONE));
assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.BYTE_ONE));
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.LONG_ONE));
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.DOUBLE_ONE));
}
public void testInvokeExactMethod() throws Exception {
assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo",
ArrayUtils.EMPTY_CLASS_ARRAY));
assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo",
(Class[]) null));
assertEquals("foo(String)", MethodUtils.invokeExactMethod(testBean,
"foo", ""));
assertEquals("foo(Object)", MethodUtils.invokeExactMethod(testBean,
"foo", new Object()));
assertEquals("foo(Integer)", MethodUtils.invokeExactMethod(testBean,
"foo", NumberUtils.INTEGER_ONE));
assertEquals("foo(double)", MethodUtils.invokeExactMethod(testBean,
"foo", new Object[] { NumberUtils.DOUBLE_ONE },
new Class[] { Double.TYPE }));
try {
MethodUtils
.invokeExactMethod(testBean, "foo", NumberUtils.BYTE_ONE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
try {
MethodUtils
.invokeExactMethod(testBean, "foo", NumberUtils.LONG_ONE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
try {
MethodUtils.invokeExactMethod(testBean, "foo", Boolean.TRUE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
}
public void testInvokeStaticMethod() throws Exception {
assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", ArrayUtils.EMPTY_CLASS_ARRAY));
assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", (Class[]) null));
assertEquals("bar(String)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", ""));
assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", new Object()));
assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", Boolean.TRUE));
assertEquals("bar(Integer)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.INTEGER_ONE));
assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", NumberUtils.BYTE_ONE));
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.LONG_ONE));
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
}
public void testInvokeExactStaticMethod() throws Exception {
assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", ArrayUtils.EMPTY_CLASS_ARRAY));
assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", (Class[]) null));
assertEquals("bar(String)", MethodUtils.invokeExactStaticMethod(
TestBean.class, "bar", ""));
assertEquals("bar(Object)", MethodUtils.invokeExactStaticMethod(
TestBean.class, "bar", new Object()));
assertEquals("bar(Integer)", MethodUtils.invokeExactStaticMethod(
TestBean.class, "bar", NumberUtils.INTEGER_ONE));
assertEquals("bar(double)", MethodUtils.invokeExactStaticMethod(
TestBean.class, "bar", new Object[] { NumberUtils.DOUBLE_ONE },
new Class[] { Double.TYPE }));
try {
MethodUtils.invokeExactStaticMethod(TestBean.class, "bar",
NumberUtils.BYTE_ONE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
try {
MethodUtils.invokeExactStaticMethod(TestBean.class, "bar",
NumberUtils.LONG_ONE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
try {
MethodUtils.invokeExactStaticMethod(TestBean.class, "bar",
Boolean.TRUE);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException e) {
}
}
public void testGetAccessibleInterfaceMethod() throws Exception {
Class[][] p = { ArrayUtils.EMPTY_CLASS_ARRAY, null };
for (int i = 0; i < p.length; i++) {
Method method = TestMutable.class.getMethod("getValue", p[i]);
Method accessibleMethod = MethodUtils.getAccessibleMethod(method);
assertNotSame(accessibleMethod, method);
assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
}
}
public void testGetAccessibleInterfaceMethodFromDescription()
throws Exception {
Class[][] p = { ArrayUtils.EMPTY_CLASS_ARRAY, null };
for (int i = 0; i < p.length; i++) {
Method accessibleMethod = MethodUtils.getAccessibleMethod(
TestMutable.class, "getValue", p[i]);
assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
}
}
public void testGetAccessiblePublicMethod() throws Exception {
assertSame(MutableObject.class, MethodUtils.getAccessibleMethod(
MutableObject.class.getMethod("getValue",
ArrayUtils.EMPTY_CLASS_ARRAY)).getDeclaringClass());
}
public void testGetAccessiblePublicMethodFromDescription() throws Exception {
assertSame(MutableObject.class, MethodUtils.getAccessibleMethod(
MutableObject.class, "getValue", ArrayUtils.EMPTY_CLASS_ARRAY)
.getDeclaringClass());
}
public void testGetMatchingAccessibleMethod() throws Exception {
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
ArrayUtils.EMPTY_CLASS_ARRAY, ArrayUtils.EMPTY_CLASS_ARRAY);
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
null, ArrayUtils.EMPTY_CLASS_ARRAY);
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(String.class), singletonArray(String.class));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Object.class), singletonArray(Object.class));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Boolean.class), singletonArray(Object.class));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Byte.class), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Byte.TYPE), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Short.class), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Short.TYPE), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Character.class), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Character.TYPE), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Integer.class), singletonArray(Integer.class));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Long.class), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Long.TYPE), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Float.class), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Float.TYPE), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Double.class), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Double.TYPE), singletonArray(Double.TYPE));
}
private void expectMatchingAccessibleMethodParameterTypes(Class cls,
String methodName, Class[] requestTypes, Class[] actualTypes) {
Method m = MethodUtils.getMatchingAccessibleMethod(cls, methodName,
requestTypes);
assertTrue(toString(m.getParameterTypes()) + " not equals "
+ toString(actualTypes), Arrays.equals(actualTypes, m
.getParameterTypes()));
}
private String toString(Class[] c) {
return Arrays.asList(c).toString();
}
public void testSetCacheMethods() throws Exception {
MethodUtils.clearCache();
MethodUtils.setCacheMethods(true);
MethodUtils.invokeMethod(testBean, "foo", "");
assertEquals(1, MethodUtils.clearCache());
assertEquals(0, MethodUtils.clearCache());
MethodUtils.setCacheMethods(false);
MethodUtils.invokeMethod(testBean, "foo", "");
assertEquals(0, MethodUtils.clearCache());
MethodUtils.setCacheMethods(true);
}
private Class[] singletonArray(Class c) {
Class[] result = (Class[]) classCache.get(c);
if (result == null) {
result = new Class[] { c };
classCache.put(c, result);
}
return result;
}
}