2011-07-05 16 views
6

Tôi đã triển khai ClassFileTransformer cho một javaagent bằng ASM. Bởi vì nó có một số lỗi, tôi muốn viết một trường hợp thử nghiệm JUnit cho nó. Làm thế nào để tôi làm điều này?Làm cách nào để kiểm tra ClassFileTransformer/javaagent?

Sử dụng pseudo-code tôi nghĩ dọc theo dòng:

// 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()); 

Bây giờ câu hỏi là: Làm thế nào để tự tải và chuyển đổi chủ đề và làm cho JVM/Classloader sử dụng phiên bản thao túng của tôi về nó? Hay tôi hoàn toàn bỏ lỡ điều gì đó?

Trả lời

6

Tôi hiểu rồi. Một trong những nhu cầu để thực hiện một ClassLoader riêng mà thực hiện chuyển đổi tương tự với đối tượng thử nghiệm là ClassFileTransformer (ví dụ: gọi nó). Và tất nhiên lớp chủ đề có thể chưa được tải, vì vậy có thể không có bất kỳ cách sử dụng trực tiếp nào. Vì vậy, tôi đã sử dụng API phản chiếu Java để thực thi các phương thức của lớp chủ đề.

Trong một tập tin riêng biệt:

public static class Subject { 
    public void doSomething(){...} 
} 

Trong thử nghiệm:

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()); 
} 
Các vấn đề liên quan