blob: c396ae3af6addf07391a204372b4745283f6660c [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.beanutils2;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.commons.beanutils2.priv.PrivateBeanFactory;
import org.apache.commons.beanutils2.priv.PublicSubBean;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* <p> Test case for {@code MethodUtils} </p>
*
*/
public class MethodUtilsTestCase extends TestCase {
/**
* Construct a new instance of this test case.
*
* @param name Name of the test case
*/
public MethodUtilsTestCase(final String name) {
super(name);
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() {
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() {
return new TestSuite(MethodUtilsTestCase.class);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
}
/**
* <p> Test {@code getAccessibleMethod}.
*/
public void testGetAccessibleMethod() {
// easy bit first - find a public method
final Method method = MethodUtils.getAccessibleMethod
(TestBean.class, "setStringProperty", String.class);
assertMethod(method, "setStringProperty");
}
public void testGetAccessibleMethodFromInterface() {
Method method;
// trickier this one - find a method in a direct interface
method = MethodUtils.getAccessibleMethod
(PrivateBeanFactory.create().getClass(),
"methodBar",
String.class);
assertMethod(method, "methodBar");
}
public void testGetAccessibleMethodIndirectInterface() {
Method method;
// trickier this one - find a method in a indirect interface
method = MethodUtils.getAccessibleMethod
(PrivateBeanFactory.createSubclass().getClass(),
"methodBaz",
String.class);
assertMethod(method, "methodBaz");
}
private static void assertMethod(final Method method, final String methodName) {
assertNotNull(method);
assertEquals("Method is not named correctly", methodName,
method.getName());
assertTrue("Method is not public",
Modifier.isPublic(method.getModifiers()));
}
/**
* <p> Test {@code invokeExactMethod}.
*/
public void testInvokeExactMethod() throws Exception {
final TestBean bean = new TestBean();
final Object ret = MethodUtils.invokeExactMethod(bean, "setStringProperty", "TEST");
assertNull(ret);
assertEquals("Method ONE was invoked", "TEST", bean.getStringProperty());
}
public void testInvokeExactMethodFromInterface() throws Exception {
final Object ret = MethodUtils.invokeExactMethod(
PrivateBeanFactory.create(),
"methodBar",
"ANOTHER TEST");
assertEquals("Method TWO wasn't invoked correctly", "ANOTHER TEST", ret);
}
public void testInvokeExactMethodIndirectInterface() throws Exception {
final Object ret = MethodUtils.invokeExactMethod(
PrivateBeanFactory.createSubclass(),
"methodBaz",
"YET ANOTHER TEST");
assertEquals("Method TWO was invoked correctly", "YET ANOTHER TEST", ret);
}
public void testInvokeExactMethodNullArray() throws Exception {
final Object result = MethodUtils.invokeExactMethod(
new AlphaBean("parent"),
"getName",
null);
assertEquals("parent", result);
}
public void testInvokeExactMethodNullArrayNullArray() throws Exception {
final Object result = MethodUtils.invokeExactMethod(
new AlphaBean("parent"),
"getName",
null,
null);
assertEquals("parent", result);
}
public void testInvokeExactMethodNull() throws Exception {
final Object object = new Object();
final Object result = MethodUtils.invokeExactMethod(object, "toString", (Object) null);
assertEquals(object.toString(), result);
}
/**
* <p> Test {@code invokeMethod}.
*/
public void testInvokeMethod() throws Exception {
final AbstractParent parent = new AlphaBean("parent");
final BetaBean childOne = new BetaBean("ChildOne");
assertEquals(
"Cannot invoke through abstract class (1)",
"ChildOne",
MethodUtils.invokeMethod(parent, "testAddChild", childOne));
}
public void testInvokeMethodObject() throws Exception {
final AbstractParent parent = new AlphaBean("parent");
final Child childTwo = new AlphaBean("ChildTwo");
assertEquals("Cannot invoke through interface (1)",
"ChildTwo",
MethodUtils.invokeMethod(parent, "testAddChild", childTwo));
}
public void testInvokeMethodArray() throws Exception {
final AbstractParent parent = new AlphaBean("parent");
final AlphaBean childTwo = new AlphaBean("ChildTwo");
final Object[] params = new Object[2];
params[0] = "parameter";
params[1] = childTwo;
assertEquals("Cannot invoke through abstract class",
"ChildTwo",
MethodUtils.invokeMethod(parent, "testAddChild2", params));
}
public void testInvokeMethodUnknown() throws Exception {
// test that exception is correctly thrown when a method cannot be found with matching params
try {
final AbstractParent parent = new AlphaBean("parent");
final BetaBean childOne = new BetaBean("ChildOne");
MethodUtils.invokeMethod(parent, "bogus", childOne);
fail("No exception thrown when no appropriate method exists");
} catch (final NoSuchMethodException expected) {
// this is what we're expecting!
}
}
public void testInvokeMethodNullArray() throws Exception {
final Object result = MethodUtils.invokeMethod(
new AlphaBean("parent"),
"getName",
null);
assertEquals("parent", result);
}
public void testInvokeMethodNullArrayNullArray() throws Exception {
final Object result = MethodUtils.invokeMethod(
new AlphaBean("parent"),
"getName",
null,
null);
assertEquals("parent", result);
}
public void testInvokeMethodNull() throws Exception {
final Object object = new Object();
final Object result = MethodUtils.invokeMethod(object, "toString", (Object) null);
assertEquals(object.toString(), result);
}
public void testInvokeMethodPrimitiveBoolean() throws Exception {
final PrimitiveBean bean = new PrimitiveBean();
MethodUtils.invokeMethod(bean, "setBoolean", Boolean.FALSE);
assertEquals("Call boolean property using invokeMethod", false, bean.getBoolean());
}
public void testInvokeMethodPrimitiveFloat() throws Exception {
final PrimitiveBean bean = new PrimitiveBean();
MethodUtils.invokeMethod(bean, "setFloat", Float.valueOf(20.0f));
assertEquals("Call float property using invokeMethod", 20.0f, bean.getFloat(), 0.01f);
}
public void testInvokeMethodPrimitiveLong() throws Exception {
final PrimitiveBean bean = new PrimitiveBean();
MethodUtils.invokeMethod(bean, "setLong", Long.valueOf(10));
assertEquals("Call long property using invokeMethod", 10, bean.getLong());
}
public void testInvokeMethodPrimitiveInt() throws Exception {
final PrimitiveBean bean = new PrimitiveBean();
MethodUtils.invokeMethod(bean, "setInt", Integer.valueOf(12));
assertEquals("Set int property using invokeMethod", 12, bean.getInt());
}
public void testInvokeMethodPrimitiveDouble() throws Exception {
final PrimitiveBean bean = new PrimitiveBean();
MethodUtils.invokeMethod(bean, "setDouble", Double.valueOf(25.5d));
assertEquals("Set double property using invokeMethod", 25.5d, bean.getDouble(), 0.01d);
}
public void testStaticInvokeMethod() throws Exception {
Object value = null;
int current = TestBean.currentCounter();
value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
MethodUtils.invokeStaticMethod(TestBean.class, "incrementCounter", new Object[0]);
current++;
value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
MethodUtils.invokeStaticMethod(TestBean.class, "incrementCounter", new Object[] { new Integer(8) } );
current += 8;
value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
MethodUtils.invokeExactStaticMethod(TestBean.class, "incrementCounter",
new Object[] { new Integer(8) }, new Class[] { Number.class } );
current += 16;
value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", new Object[0]);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
}
public void testInvokeStaticMethodNull() throws Exception {
final int current = TestBean.currentCounter();
final Object value = MethodUtils.invokeStaticMethod(TestBean.class, "currentCounter", (Object) null);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
}
public void testInvokeExactStaticMethodNull() throws Exception {
final int current = TestBean.currentCounter();
final Object value = MethodUtils.invokeExactStaticMethod(TestBean.class, "currentCounter", (Object) null);
assertEquals("currentCounter value", current, ((Integer) value).intValue());
}
/**
* Simple tests for accessing static methods via invokeMethod().
*/
public void testSimpleStatic1() {
final TestBean bean = new TestBean();
Object value = null;
int current = TestBean.currentCounter();
try {
// Return initial value of the counter
value = MethodUtils.invokeMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via no-arguments version
MethodUtils.invokeMethod
(bean, "incrementCounter", new Object[0], new Class[0]);
// Validate updated value
current++;
value = MethodUtils.invokeMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via specified-argument version
MethodUtils.invokeMethod
(bean, "incrementCounter",
new Object[] { new Integer(5) },
new Class[] { Integer.TYPE });
// Validate updated value
current += 5;
value = MethodUtils.invokeMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
} catch (final Exception e) {
fail("Threw exception" + e);
}
}
/**
* Simple tests for accessing static methods via invokeExactMethod().
*/
public void testSimpleStatic2() {
final TestBean bean = new TestBean();
Object value = null;
int current = TestBean.currentCounter();
try {
// Return initial value of the counter
value = MethodUtils.invokeExactMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via no-arguments version
MethodUtils.invokeExactMethod
(bean, "incrementCounter", new Object[0], new Class[0]);
// Validate updated value
current++;
value = MethodUtils.invokeExactMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via specified-argument version
MethodUtils.invokeExactMethod
(bean, "incrementCounter",
new Object[] { new Integer(5) },
new Class[] { Integer.TYPE });
// Validate updated value
current += 5;
value = MethodUtils.invokeExactMethod
(bean, "currentCounter", new Object[0], new Class[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
} catch (final Exception e) {
fail("Threw exception" + e);
}
}
/**
* Simple tests for accessing static methods via getAccessibleMethod()
*/
public void testSimpleStatic3() {
Object value = null;
int current = TestBean.currentCounter();
try {
// Acquire the methods we need
final Method currentCounterMethod = MethodUtils.getAccessibleMethod
(TestBean.class, "currentCounter",
new Class[0]);
assertNotNull("currentCounterMethod exists",
currentCounterMethod);
assertEquals("currentCounterMethod name",
"currentCounter",
currentCounterMethod.getName());
assertEquals("currentCounterMethod args",
0,
currentCounterMethod.getParameterTypes().length);
assertTrue("currentCounterMethod public",
Modifier.isPublic(currentCounterMethod.getModifiers()));
assertTrue("currentCounterMethod static",
Modifier.isStatic(currentCounterMethod.getModifiers()));
final Method incrementCounterMethod1 = MethodUtils.getAccessibleMethod
(TestBean.class, "incrementCounter",
new Class[0]);
assertNotNull("incrementCounterMethod1 exists",
incrementCounterMethod1);
assertEquals("incrementCounterMethod1 name",
"incrementCounter",
incrementCounterMethod1.getName());
assertEquals("incrementCounterMethod1 args",
0,
incrementCounterMethod1.getParameterTypes().length);
assertTrue("incrementCounterMethod1 public",
Modifier.isPublic(incrementCounterMethod1.getModifiers()));
assertTrue("incrementCounterMethod1 static",
Modifier.isStatic(incrementCounterMethod1.getModifiers()));
final Method incrementCounterMethod2 = MethodUtils.getAccessibleMethod
(TestBean.class, "incrementCounter",
new Class[] { Integer.TYPE });
assertNotNull("incrementCounterMethod2 exists",
incrementCounterMethod2);
assertEquals("incrementCounterMethod2 name",
"incrementCounter",
incrementCounterMethod2.getName());
assertEquals("incrementCounterMethod2 args",
1,
incrementCounterMethod2.getParameterTypes().length);
assertTrue("incrementCounterMethod2 public",
Modifier.isPublic(incrementCounterMethod2.getModifiers()));
assertTrue("incrementCounterMethod2 static",
Modifier.isStatic(incrementCounterMethod2.getModifiers()));
// Return initial value of the counter
value = currentCounterMethod.invoke(null, new Object[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via no-arguments version
incrementCounterMethod1.invoke(null, new Object[0]);
// Validate updated value
current++;
value = currentCounterMethod.invoke(null, new Object[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
// Increment via specified-argument version
incrementCounterMethod2.invoke(null,
new Object[] { new Integer(5) });
// Validate updated value
current += 5;
value = currentCounterMethod.invoke(null, new Object[0]);
assertNotNull("currentCounter exists", value);
assertTrue("currentCounter type",
value instanceof Integer);
assertEquals("currentCounter value",
current,
((Integer) value).intValue());
} catch (final Exception e) {
fail("Threw exception" + e);
}
}
public void testPublicSub() throws Exception {
// make sure that bean does what it should
final PublicSubBean bean = new PublicSubBean();
assertEquals("Start value (foo)", bean.getFoo(), "This is foo");
assertEquals("Start value (bar)", bean.getBar(), "This is bar");
bean.setFoo("new foo");
bean.setBar("new bar");
assertEquals("Set value (foo)", bean.getFoo(), "new foo");
assertEquals("Set value (bar)", bean.getBar(), "new bar");
// see if we can access public methods in a default access superclass
// from a public access subclass instance
MethodUtils.invokeMethod(bean, "setFoo", "alpha");
assertEquals("Set value (foo:2)", bean.getFoo(), "alpha");
MethodUtils.invokeMethod(bean, "setBar", "beta");
assertEquals("Set value (bar:2)", bean.getBar(), "beta");
Method method = null;
try {
method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class);
} catch (final Throwable t) {
fail("getAccessibleMethod() setFoo threw " + t);
}
assertNotNull("getAccessibleMethod() setFoo is Null", method);
try {
method.invoke(bean, new Object[] {"1111"});
} catch (final Throwable t) {
fail("Invoking setFoo threw " + t);
}
assertEquals("Set value (foo:3)", "1111", bean.getFoo());
try {
method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class);
} catch (final Throwable t) {
fail("getAccessibleMethod() setBar threw " + t);
}
assertNotNull("getAccessibleMethod() setBar is Null", method);
try {
method.invoke(bean, new Object[] {"2222"});
} catch (final Throwable t) {
fail("Invoking setBar threw " + t);
}
assertEquals("Set value (bar:3)", "2222", bean.getBar());
}
public void testParentMethod() throws Exception {
final OutputStream os = new PrintStream(System.out);
final PrintStream ps = new PrintStream(System.out);
A a = new A();
MethodUtils.invokeMethod(a, "foo", os);
assertTrue("Method Invoked(1)", a.called);
a = new A();
MethodUtils.invokeMethod(a, "foo", ps);
assertTrue("Method Invoked(2)", a.called);
}
/**
* Test {@link MethodUtils#clearCache()}.
*/
public void testClearCache() throws Exception {
MethodUtils.clearCache(); // make sure it starts empty
final PublicSubBean bean = new PublicSubBean();
MethodUtils.invokeMethod(bean, "setFoo", "alpha");
assertEquals(1, MethodUtils.clearCache());
assertEquals(0, MethodUtils.clearCache());
}
/**
* Test {@link MethodUtils#setCacheMethods(boolean)}.
*/
public void testSetCacheMethods() throws Exception {
MethodUtils.setCacheMethods(true);
MethodUtils.clearCache(); // make sure it starts empty
final PublicSubBean bean = new PublicSubBean();
MethodUtils.invokeMethod(bean, "setFoo", "alpha");
assertEquals(1, MethodUtils.clearCache());
assertEquals(0, MethodUtils.clearCache());
}
public void testNoCaching() throws Exception {
// no caching
MethodUtils.setCacheMethods(false);
final PublicSubBean bean = new PublicSubBean();
MethodUtils.invokeMethod(bean, "setFoo", "alpha");
assertEquals(0, MethodUtils.clearCache());
// reset default
MethodUtils.setCacheMethods(true);
}
}