2011-07-05 5 views
6

ASM을 사용하여 javaagent에 ClassFileTransformer을 구현했습니다. 몇 가지 버그가 있기 때문에 JUnit 테스트 케이스를 작성하고 싶다. 어떻게해야합니까?ClassFileTransformer/javaagent를 테스트하는 방법은 무엇입니까?

의사 코드를 사용하여 내가 라인을 따라 생각 :

// 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/클래스 로더가 내 조작 버전을 사용해야합니까? 아니면 완전히 놓친다 고합니까?

답변

6

알겠습니다. 하나는 ClassFileTransformer (예 : 호출)과 같이 테스트 대상과 동일한 변환을 수행하는 자체 ClassLoader을 구현해야합니다. 물론 해당 주제 클래스가 아직로드되지 않았을 수 있으므로 직접 사용하지 못할 수도 있습니다. 그래서 자바 리플렉션 API를 사용하여 해당 클래스의 메소드를 실행했습니다. 테스트에서

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()); 
} 
별도의 파일에서

관련 문제