package net.bytebuddy.implementation;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.test.utility.CallTraceable;
import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
public class ExceptionMethodTest {
private static final String FOO = "foo", BAR = "bar";
@Test
public void testWithoutMessage() throws Exception {
DynamicType.Loaded<Foo> loaded = new ByteBuddy()
.subclass(Foo.class)
.method(isDeclaredBy(Foo.class))
.intercept(ExceptionMethod.throwing(RuntimeException.class))
.make()
.load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);
assertThat(loaded.getLoadedAuxiliaryTypes().size(), is(0));
assertThat(loaded.getLoaded().getDeclaredMethods().length, is(1));
assertThat(loaded.getLoaded().getDeclaredFields().length, is(0));
Foo instance = loaded.getLoaded().getDeclaredConstructor().newInstance();
assertThat(instance.getClass(), not(CoreMatchers.<Class<?>>is(Foo.class)));
assertThat(instance, instanceOf(Foo.class));
try {
instance.foo();
fail();
} catch (RuntimeException exception) {
assertThat(exception.getClass(), CoreMatchers.<Class<?>>is(RuntimeException.class));
assertThat(exception.getMessage(), nullValue());
}
instance.assertZeroCalls();
}
@Test
public void testWithMessage() throws Exception {
DynamicType.Loaded<Foo> loaded = new ByteBuddy()
.subclass(Foo.class)
.method(isDeclaredBy(Foo.class))
.intercept(ExceptionMethod.throwing(RuntimeException.class, BAR))
.make()
.load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);
assertThat(loaded.getLoadedAuxiliaryTypes().size(), is(0));
assertThat(loaded.getLoaded().getDeclaredMethods().length, is(1));
assertThat(loaded.getLoaded().getDeclaredFields().length, is(0));
Foo instance = loaded.getLoaded().getDeclaredConstructor().newInstance();
assertThat(instance.getClass(), not(CoreMatchers.<Class<?>>is(Foo.class)));
assertThat(instance, instanceOf(Foo.class));
try {
instance.foo();
fail();
} catch (RuntimeException exception) {
assertThat(exception.getClass(), CoreMatchers.<Class<?>>is(RuntimeException.class));
assertThat(exception.getMessage(), is(BAR));
}
instance.assertZeroCalls();
}
@Test
public void testWithNonDeclaredCheckedException() throws Exception {
DynamicType.Loaded<Foo> loaded = new ByteBuddy()
.subclass(Foo.class)
.method(isDeclaredBy(Foo.class))
.intercept(ExceptionMethod.throwing(Exception.class))
.make()
.load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);
assertThat(loaded.getLoadedAuxiliaryTypes().size(), is(0));
assertThat(loaded.getLoaded().getDeclaredMethods().length, is(1));
assertThat(loaded.getLoaded().getDeclaredFields().length, is(0));
Foo instance = loaded.getLoaded().getDeclaredConstructor().newInstance();
assertThat(instance.getClass(), not(CoreMatchers.<Class<?>>is(Foo.class)));
assertThat(instance, instanceOf(Foo.class));
try {
instance.foo();
fail();
} catch (Exception exception) {
assertThat(exception.getClass(), CoreMatchers.<Class<?>>is(Exception.class));
assertThat(exception.getMessage(), nullValue());
}
instance.assertZeroCalls();
}
@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(ExceptionMethod.class).apply();
ObjectPropertyAssertion.of(ExceptionMethod.ConstructionDelegate.ForDefaultConstructor.class).refine(new ObjectPropertyAssertion.Refinement<TypeDescription>() {
@Override
public void apply(TypeDescription mock) {
when(mock.getDeclaredMethods()).thenReturn(new MethodList.ForLoadedMethods(Object.class));
}
}).apply();
ObjectPropertyAssertion.of(ExceptionMethod.ConstructionDelegate.ForStringConstructor.class).refine(new ObjectPropertyAssertion.Refinement<TypeDescription>() {
@Override
public void apply(TypeDescription mock) {
when(mock.getDeclaredMethods()).thenReturn(new MethodList.ForLoadedMethods(String.class));
}
}).apply();
}
public static class Foo extends CallTraceable {
public void foo() {
register(FOO);
}
}
}