Я понял. Нужно реализовать собственный ClassLoader
, который выполняет то же преобразование с испытуемым, что и ClassFileTransformer
(например, вызывает его). И, конечно, предметный класс может быть еще не загружен, поэтому его использование может быть невозможно. Поэтому я использовал API отражения Java для выполнения методов класса объекта.
В отдельном файле:
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());
}