【发布时间】:2022-11-10 16:46:39
【问题描述】:
我想创建一个从 Java 反射实现 InvocationHandler 接口的模拟库类。
这是我创建的模板:
import java.lang.reflect.*;
import java.util.*;
class MyMock implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// todo
}
public MyMock when(String method, Object[] args) {
// todo
}
public void thenReturn(Object val) {
// todo
}
}
when 和 thenReturn 方法是链式方法。
然后when 方法注册给定的模拟参数。
thenReturn 方法注册给定模拟参数的预期返回值。
另外,如果代理接口调用方法或使用未注册的参数,我想抛出 java.lang.IllegalArgumentException。
这是一个示例界面:
interface CalcInterface {
int add(int a, int b);
String add(String a, String b);
String getValue();
}
这里我们有两个重载的add 方法。
这是一个测试我想要实现的模拟类的程序。
class TestApplication {
public static void main(String[] args) {
MyMock m = new MyMock();
CalcInterface ref = (CalcInterface) Proxy.newProxyInstance(MyMock.class.getClassLoader(), new Class[]{CalcInterface.class}, m);
m.when("add", new Object[]{1,2}).thenReturn(3);
m.when("add", new Object[]{"x","y"}).thenReturn("xy");
System.out.println(ref.add(1,2)); // prints 3
System.out.println(ref.add("x","y")); // prints "xy"
}
}
这是我迄今为止实现的用于检查 CalcInterface 中的方法的代码:
class MyMock implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
int n = args.length;
if(n == 2 && method.getName().equals("add")) {
Object o1 = args[0], o2 = args[1];
if((o1 instanceof String) && (o2 instanceof String)) {
String s1 = (String) o1, s2 = (String) o2;
return s1+ s2;
} else if((o1 instanceof Integer) && (o2 instanceof Integer)) {
int s1 = (Integer) o1, s2 = (Integer) o2;
return s1+ s2;
}
}
throw new IllegalArgumentException();
}
public MyMock when(String method, Object[] args) {
return this;
}
public void thenReturn(Object val) {
}
}
在这里,我只检查名称为 add 并具有 2 个参数的方法,它们的类型为 String 或 Integer。
但是我想以一种通用的方式创建这个MyMock 类,支持不同的接口,而不仅仅是CalcInterface,还支持不同的方法,而不仅仅是我在这里实现的add 方法。
【问题讨论】:
-
为什么
thenReturn不返回任何东西?
标签: java reflection java-8 interface mocking