/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed 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.springframework.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.*;
/**
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @author Sam Brannen
* @since 21.11.2003
*/
public class MethodInvokerTests {
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void plainMethodInvoker() throws Exception {
// sanity check: singleton, non-static should work
TestClass1 tc1 = new TestClass1();
MethodInvoker mi = new MethodInvoker();
mi.setTargetObject(tc1);
mi.setTargetMethod("method1");
mi.prepare();
Integer i = (Integer) mi.invoke();
assertEquals(1, i.intValue());
// sanity check: check that argument count matching works
mi = new MethodInvoker();
mi.setTargetClass(TestClass1.class);
mi.setTargetMethod("supertypes");
mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello"});
mi.prepare();
assertEquals("hello", mi.invoke());
mi = new MethodInvoker();
mi.setTargetClass(TestClass1.class);
mi.setTargetMethod("supertypes2");
mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello", "bogus"});
mi.prepare();
assertEquals("hello", mi.invoke());
// Sanity check: check that argument conversion doesn't work with plain MethodInvoker
mi = new MethodInvoker();
mi.setTargetClass(TestClass1.class);
mi.setTargetMethod("supertypes2");
mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello", Boolean.TRUE});
exception.expect(NoSuchMethodException.class);
mi.prepare();
}
@Test
public void stringWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {"no match"});
exception.expect(NoSuchMethodException.class);
methodInvoker.prepare();
}
@Test
public void purchaserWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new Purchaser()});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("purchaser: hello", greeting);
}
@Test
public void shopperWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new Shopper()});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("purchaser: may I help you?", greeting);
}
@Test
public void salesmanWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new Salesman()});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("greetable: how are sales?", greeting);
}
@Test
public void customerWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new Customer()});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("customer: good day", greeting);
}
@Test
public void regularWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new Regular("Kotter")});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("regular: welcome back Kotter", greeting);
}
@Test
public void vipWithMethodInvoker() throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(new Greeter());
methodInvoker.setTargetMethod("greet");
methodInvoker.setArguments(new Object[] {new VIP("Fonzie")});
methodInvoker.prepare();
String greeting = (String) methodInvoker.invoke();
assertEquals("regular: whassup dude?", greeting);
}
public static class TestClass1 {
public static int _staticField1;
public int _field1 = 0;
public int method1() {
return ++_field1;
}
public static int staticMethod1() {
return ++TestClass1._staticField1;
}
public static void voidRetvalMethod() {
}
public static void nullArgument(Object arg) {
}
public static void intArgument(int arg) {
}
public static void intArguments(int[] arg) {
}
public static String supertypes(Collection<?> c, Integer i) {
return i.toString();
}
public static String supertypes(Collection<?> c, List<?> l, String s) {
return s;
}
public static String supertypes2(Collection<?> c, List<?> l, Integer i) {
return i.toString();
}
public static String supertypes2(Collection<?> c, List<?> l, String s, Integer i) {
return s;
}
public static String supertypes2(Collection<?> c, List<?> l, String s, String s2) {
return s;
}
}
@SuppressWarnings("unused")
public static class Greeter {
// should handle Salesman (only interface)
public String greet(Greetable greetable) {
return "greetable: " + greetable.getGreeting();
}
// should handle Shopper (beats Greetable since it is a class)
protected String greet(Purchaser purchaser) {
return "purchaser: " + purchaser.getGreeting();
}
// should handle Customer (exact match)
String greet(Customer customer) {
return "customer: " + customer.getGreeting();
}
// should handle Regular (exact) and VIP (closest match)
private String greet(Regular regular) {
return "regular: " + regular.getGreeting();
}
}
private interface Greetable {
String getGreeting();
}
private interface Person extends Greetable {
}
private static class Purchaser implements Greetable {
@Override
public String getGreeting() {
return "hello";
}
}
private static class Shopper extends Purchaser implements Person {
@Override
public String getGreeting() {
return "may I help you?";
}
}
private static class Salesman implements Person {
@Override
public String getGreeting() {
return "how are sales?";
}
}
private static class Customer extends Shopper {
@Override
public String getGreeting() {
return "good day";
}
}
private static class Regular extends Customer {
private String name;
public Regular(String name) {
this.name = name;
}
@Override
public String getGreeting() {
return "welcome back " + name ;
}
}
private static class VIP extends Regular {
public VIP(String name) {
super(name);
}
@Override
public String getGreeting() {
return "whassup dude?";
}
}
}