作为一个大项目的一部分,我正在尝试实现一些我不确定的可能性,所以我很想看看是否有人有任何建议!
整个系统:
总的来说,我的系统应该能够提供一个JUnit测试类,它匹配一些提供的接口。然后将给出不实现此接口的类,但需要检查它们是否能够(如果它们实现了所有必要的方法,则为a.k.a.)。如果是这样,应该进行一些转换,以便可以针对它运行JUnit测试类。
到目前为止,我已实施:
- 使用URLClassLoader
加载给定路径和名称的其他类的包
- 运行JUnit测试用例并使用JUnitCore
问题:
1.首先,当测试设计为与接口匹配时,如何针对实现接口的类运行JUnit测试?我如何(在运行时)指示接口测试的实例是加载的类?
感谢任何可能有助于解决部分问题的建议。我感谢您的描述可能缺乏,所以如果您有任何可以帮助您给出任何答案的额外信息,请发表评论!
答案 0 :(得分:1)
您可以使用反射API执行所需操作。听起来你应该从the tutorial开始,然后回到这里寻找具体问题。给定一个Class对象,您可以检查它是否实现了给定的接口,创建它的实例,然后将其视为任何其他类。
编辑:我认为我没有从你的问题中得到这个,但在这种情况下,你正在寻找反射API的Proxy部分。
答案 1 :(得分:1)
我怎么能运行JUnit测试 一个确实实现的类 测试设计时的界面 匹配界面
由于您拥有该类,因此可以使用该类提供的isAssignableFrom方法,以便
Class loadedJunitClass = clazz;
MyInterface impl = null;
if(MyInterface.class.isAssignableFrom(loadedJunitClass )){
impl = (MyInterface) loadedJunitClass.newInstance();
}
对于第二个问题,您可以检查每个方法并查看1.如果存在具有与接口中定义的方法名称相同的方法,则2.如果方法返回类型与接口相同,则为3.如果方法参数类型和长度是相同的。当然,2和3可能很难做到正确。
此时我只想创建该接口的实例(匿名或私有类),创建该匹配类的newInstance。并通过接口方法中的反射调用方法。
现在,你可以通过反思来完成它。我不是想象你想象的反思:)
答案 2 :(得分:1)
问题的第一部分;如果您要为要测试的类加载了Class实例,则可以使用newInstance()构造一个(如果它具有默认构造函数),或者如果需要传递参数,则可以通过getConstructor方法构造。您应该能够从类加载器中获取此Class实例。
第二部分。您应该能够通过getMethods()(再次在Class实例上)检查公共方法,然后查看返回的数组以获取所需的方法。 Method类上有一些方法可以返回有关参数,异常和返回类型的信息,以验证它们是否符合您的要求。
但是,我很确定在运行时无法修改类来添加接口。通过修改字节代码可能是可能的,但我不知道。
另一种方法是编写测试以通过反射调用所有方法,然后对象的类型只是它具有正确的方法(您已经检查过)并不重要。
答案 3 :(得分:1)
如果你想让任意类在运行时实现给定接口,如果它的公共API与接口匹配,那么你在Java中有几个选项。创建java.lang.Proxy
以桥接目标类,公开YourInterface
是最简单的方法。
YourInterface i = (YourInterface) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[]{YourInterface.class},
new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//run method on your target class here using reflection
}
});
您还可以在AspectJ中使用mixins,或者使用CGLIB将目标类子类化,并在运行时添加接口。但是代理方法并不是那么难以实现的。