실행 중에 JUnit4 테스트를 실행하고 Bytebuddy (버전 1.2.3)로 테스트를 가로 채어 테스트에서 어떤 메서드가 뮤 테이터인지 확인하려고합니다. 메소드 (기본 클래스의 변수 변경). 전체 프로세스는 정상적인 JUnit 테스트로 정상적으로 작동하지만 정확한 테스트를 실행하려고하지만 junit.framework.TestCase를 확장하면 프로세스가 충돌합니다. 오류를 다음과 같이 제한 할 수있었습니다. 디버그하려고하면 충돌을 일으키는 클래스 인 clazz="junit.framework.testcase"
(Interceptor.java 참조)을 나타내는 많은 항목이 표시됩니다.junit.framework.TestCase가 Bytebuddy의 @Origin에 의해 차단되지 않도록 제외하는 방법
내 질문은 다음과 같습니다. TestCase 클래스를 가로채는 것을 어떻게 제외시킬 수 있습니까? 나는 다음과 같은 문장으로 그것을 시도 :
ElementMatchers.not(ElementMatchers.namedIgnoreCase("junit.framework.testcase"))
ElementMatchers.not(ElementMatchers.is(junit.framework.TestCase.class))
- 다음 코드로
ElementMatchers.not(ElementMatchers.nameContains("junit.framework"))
, 나는 콘솔 출력으로받을하려고 :
intercepted: tests.producttest
running testSquarPrice
intercepted: example.product
finished testSquarPrice
하지만, 결과는 항상 내 시도에도 다음 출력입니다. junit.framework.testcase
을 제외하려면 다음은
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: junit.framework.testcase
intercepted: tests.producttest
running testSquarPrice
intercepted: example.product
finished testSquarPrice
intercepted: junit.framework.testcase
내 코드입니다 :
Starter.java
import introspect.Agent;
public class Starter {
public static void main(String[] args) {
Agent x = new Agent();
x.run();
}
}
에게 Agent.java
package introspect;
import org.junit.runner.Request;
import net.bytebuddy.dynamic.DynamicType.Builder;
public class Agent {
public Agent() {
final Interceptor interceptor = new Interceptor();
new AgentBuilder.Default()
.type(ElementMatchers.not(ElementMatchers.named("junit.framework.testcase"))
.and(ElementMatchers.nameStartsWithIgnoreCase("example")
.or(ElementMatchers.nameEndsWithIgnoreCase("test"))),
ElementMatchers.not(ElementMatchers.isBootstrapClassLoader()))
.transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> builder, TypeDescription arg1, ClassLoader arg2) {
return builder
.method(ElementMatchers.isPublic()
.and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class))))
.intercept(MethodDelegation.to(interceptor).filter(ElementMatchers.named("intercept")));
}
}).installOn(ByteBuddyAgent.install());
}
public void run() {
JUnitCore junit = new JUnitCore();
Request request = Request.method(ProductTest.class, "testSquarPrice");
junit.run(request);
}
}
Interceptor.java
package introspect;
import java.lang.reflect.Method;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
public class Interceptor {
@RuntimeType
public Object intercept(@Origin Method m, @SuperCall Callable<?> zuper, @AllArguments Object[] args,
@This Object thiz) throws Exception {
// get the name of the intercepted class
String clazz = m.getDeclaringClass().getName().toLowerCase();
System.out.println("intercepted: "+clazz);
return zuper.call();
}
}
을
ProductTest.java
package tests;
public class ProductTest extends TestCase{
@Test
public void testSquarPrice() {
System.out.println("running testSquarPrice");
Product p = new Product();
int re = p.squarPrice(10);
assertTrue(re == 100);
System.out.println("finished testSquarPrice");
}
}
Product.java ElementMatchers.not(ElementMatchers.is(junit.framework.TestCase.class))
으로
package example;
public class Product {
public int count, price, index;
public Product() {
index = 0;
}
public int squarPrice(int price) {
index++;
return price * price;
}
}
고맙습니다. 첫 번째 솔루션은 완벽하게 작동했으며 두 번째 솔루션은 앞으로 도움이 될 수 있습니다. – Jacktraror