我使用ASM为javaagent实现了一个ClassFileTransformer。因为它有一些bug,所以我想为它写一个JUnit测试用例。我该怎么做呢?
使用伪代码,我是这样想的:
// Have a test class as subject
public static class Subject {
public void doSomething(){...}
}
// Manually load and transform the subject
...?
// Normally execute some now transformed methods of the subject
new Subject().doSomething();
// Check the result of the call (i.e. whether the correct attached methods were called)
Assert.assertTrue(MyClassFileTransformer.wasCalled());现在的问题是:如何手动加载和转换主题,并使JVM/Classloader使用我的操作版本?还是我完全漏掉了什么?
发布于 2011-07-07 16:40:30
这样啊,原来是这么回事。一个人需要实现自己的ClassLoader,它对测试对象执行与ClassFileTransformer相同的转换(例如,调用它)。当然,subject类可能还没有装入,所以可能没有任何直接的用法。所以我使用Java反射API来执行subject类的方法。
在一个单独的文件中:
public static class Subject {
public void doSomething(){...}
}在测试中:
private static class TransformingClassLoader extends ClassLoader {
private final String className;
public TransformingClassLoader(String className) {
super();
this.className = className;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.equals(className)) {
byte[] byteBuffer = instrumentByteCode(fullyQualifiedSubjectClass);
return defineClass(className, byteBuffer, 0, byteBuffer.length);
}
return super.loadClass(name);
}
}
@Test
public void testSubject(){
ClassLoader classLoader = new TransformingClassLoader(fullyQualifiedSubjectClass);
Class<?> subjectClass = classLoader.loadClass(fullyQualifiedSubjectClass);
Constructor<?> constructor = subjectClass.getConstructor();
Object subject = constructor.newInstance();
Method doSomething = subjectClass.getMethod("doSomething");
doSomething.invoke(subject);
Assert.assertTrue(MyClassFileTransformer.wasCalled());
}https://stackoverflow.com/questions/6586681
复制相似问题