我想做的是一个方法
- 生成类X的实例(在arg中传递的类变量)和
- 重写它的一些方法
- 不包含默认构造函数(例如所有带参数的构造函数)
- 构造函数调用同一类中的非私有方法
最初我认为使用反射或类似的东西很简单,然后我发现在实现我的需求时有限制。
- For reflection:只能通过java.lang.reflect.Proxy覆盖"interface"http://download.oracle.com/javase/1.3/docs/guide/reflection/proxy.html
- for cglib:它不能创建没有默认构造函数和调用非私有成员方法的构造函数的实例http://insufficientinformation.blogspot.com/2007/12/spring-dynamic-proxies-vs-cglib-proxies.html
我认为这是可以实现的,因为Mockito可以在运行时做各种方法注入。
请大家多多指教,谢谢。
伪码I图像是这样的:
createAndOverride(Class X) {
X newObj = X.newInstance(args) {
@override
methodOfX(args2) {
...
}
}
return newObj;
}
- 原问题场景
我打算测试一个类,它有几个方法调用X1.get(), X2.get(), X3.get()
在一些测试用例中,我需要使Xn.get()返回一些我可以控制的测试(例如null)
由于以下约束:
- 但是由于JMock 1.0的模拟工具限制(我没有控制:(),所以我不能简单地模拟Xn.get()来返回"someSpecifiedObjects"
- Xn没有空的构造函数和调用非私有成员的构造函数
我的解决方法是自己制作Xn类,并将它们传递到测试用例,让Cn.get()是预期的
代码示例:
ClassToTest.SomeMethod(new X1() {
@override
get() {
return someSpecifiedObjects;
}
});
这种东西在测试用例中展开。
因此,为了减少重复的代码,我想构建一个方法来生成Xn实例,并指定用于测试的重写方法。例如
X1 x1 = createAndOverride(X1);
那么,这篇文章的问题就来了
您正在寻找类似javassist的东西吗?您可以在运行时检测代码并注入方法。我个人尽量避免字节码操作。您能在代码库中不使用这些重写,而只在运行时使用吗?可能是包装纸之类的东西?
所以我认为你需要的是一个类似于c#的Reflection.Emit
的功能:
- 使用反射。发出以创建实现接口 的类
- Java等效的反射。发出 使用JavaClassCreator动态创建Java类
虽然我自己没有这样做过,但我认为你应该能够使用反射/发射和动态类型创建来实现你想要的。然而,我仍然想提到的是,如果你试图测试的"功能"不是在你正在测试的函数的代码路径中,那么你可能根本就不应该测试它。例如:
SomeObjectInterface get()
{
if(_someObjectStateIsSet)
{
// Return a concrete implementation A
return new ConcreteImplA();
}
else
{
// Return a concrete implementation B
return new ConcreteImplB();
}
}
在本例中,get没有返回null
的代码路径,因此不需要测试null
。我不确定我是否100%正确地理解了你的问题,特别是为什么你要测试null
,但考虑上面的建议,看看什么对你有用。