package de.bechte.junit.runners.util; import de.bechte.junit.stubs.Class1stLevel; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import java.util.Stack; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; public class ReflectionUtilTest { private Stack<Class<?>> stackForClasses(Class<?>... classes) { Stack<Class<?>> stack = new Stack<Class<?>>(); for (Class<?> c : classes) stack.push(c); return stack; } @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void whenGetEnclosingInstanceIsCalledWithNull_anIllegalArgumentExceptionIsThrown() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Target must not be null!"); ReflectionUtil.getEnclosingInstance(null); } @Test public void whenGetEnclosingInstanceIsCalledWithFirstLevelInstance_nullIsReturned() throws Exception { Object enclosingInstance = ReflectionUtil.getEnclosingInstance(new ReflectionUtilTest()); assertThat(enclosingInstance, is(nullValue())); } @Test public void whenGetEnclosingInstanceIsCalledWith2ndLevelInstance_1stLevelInstanceIsReturned() throws Exception { Class1stLevel class1stLevel = new Class1stLevel(); Class1stLevel.Class2ndLevel class2ndLevel = class1stLevel.new2ndLevel(); Object enclosingInstance = ReflectionUtil.getEnclosingInstance(class2ndLevel); assertThat(enclosingInstance, is(equalTo((Object) class1stLevel))); } @Test public void whenGetEnclosingInstanceIsCalledWith3rdLevelInstance_2ndLevelInstanceIsReturned() throws Exception { Class1stLevel class1stLevel = new Class1stLevel(); Class1stLevel.Class2ndLevel class2ndLevel = class1stLevel.new2ndLevel(); Class1stLevel.Class2ndLevel.Class3rdLevel class3rdLevel = class2ndLevel.new3rdLevel(); Object enclosingInstance = ReflectionUtil.getEnclosingInstance(class3rdLevel); assertThat(enclosingInstance, is(equalTo((Object) class2ndLevel))); } @Test public void whenGetEnclosingInstanceIsCalledWithStatic2ndLevelInstance_nullIsReturned() throws Exception { Object enclosingInstance = ReflectionUtil.getEnclosingInstance(new Class1stLevel.StaticClass2ndLevel()); assertThat(enclosingInstance, is(nullValue())); } @Test public void whenGetClassHierarchyIsCalledWithNull_anEmptyStackIsReturned() throws Exception { Stack<Class<?>> emptyStack = stackForClasses(); Stack<Class<?>> classHierarchy = ReflectionUtil.getClassHierarchy(null); assertThat(classHierarchy, is(equalTo(emptyStack))); } @Test public void whenGetClassHierarchyIsCalledWithFirstLevelClass_returnedStackOnlyContainsFirstLevelClass() throws Exception { Stack<Class<?>> expectedStack = stackForClasses(ReflectionUtilTest.class); Stack<Class<?>> classHierarchy = ReflectionUtil.getClassHierarchy(ReflectionUtilTest.class); assertThat(classHierarchy, is(equalTo(expectedStack))); } @Test public void whenGetClassHierarchyIsCalledWithMemberClass_returnedStackContainsMemberAndEnclosingClass() throws Exception { Stack<Class<?>> expectedStack = stackForClasses(Class1stLevel.Class2ndLevel.class, Class1stLevel.class); Stack<Class<?>> classHierarchy = ReflectionUtil.getClassHierarchy(Class1stLevel.Class2ndLevel.class); assertThat(classHierarchy, is(equalTo(expectedStack))); } @Test public void whenGetClassHierarchyIsCalledWithMember2Class_returnedStackContainsMember2AndAllEnclosingClasses() throws Exception { Stack<Class<?>> expectedStack = stackForClasses(Class1stLevel.Class2ndLevel.Class3rdLevel.class, Class1stLevel.Class2ndLevel.class, Class1stLevel.class); Stack<Class<?>> classHierarchy = ReflectionUtil.getClassHierarchy(Class1stLevel.Class2ndLevel.Class3rdLevel.class); assertThat(classHierarchy, is(equalTo(expectedStack))); } @Test public void whenGetClassHierarchyIsCalledWithStaticInnerClass_returnedStackOnlyContainsStaticInnerClass() throws Exception { Stack<Class<?>> expectedStack = stackForClasses(Class1stLevel.StaticClass2ndLevel.class); Stack<Class<?>> classHierarchy = ReflectionUtil.getClassHierarchy(Class1stLevel.StaticClass2ndLevel.class); assertThat(classHierarchy, is(equalTo(expectedStack))); } @Test public void whenCreateDeepInstanceIsCalledWithNull_anIllegalArgumentExceptionIsThrown() throws Throwable { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Stack must not be null or empty!"); ReflectionUtil.createDeepInstance(null); } @Test public void whenCreateDeepInstanceIsCalledWithEmptyStack_anIllegalArgumentExceptionIsThrown() throws Throwable { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Stack must not be null or empty!"); Stack<Class<?>> emptyStack = new Stack<Class<?>>(); ReflectionUtil.createDeepInstance(emptyStack); } @Test public void whenCreateDeepInstanceIsCalledWithStackOfSize1_anInstanceOfThatObjectIsReturned() throws Throwable { Stack<Class<?>> classHierarchy = stackForClasses(Class1stLevel.class); Object instance = ReflectionUtil.createDeepInstance(classHierarchy); assertThat(instance, is(notNullValue())); assertThat(instance, is(instanceOf(Class1stLevel.class))); } @Test public void whenCreateDeepInstanceIsCalledWithStackOfSize2_anInstanceOfThatObjectIsReturned() throws Throwable { Stack<Class<?>> classHierarchy = stackForClasses(Class1stLevel.Class2ndLevel.class, Class1stLevel.class); Object instance = ReflectionUtil.createDeepInstance(classHierarchy); assertThat(instance, is(notNullValue())); assertThat(instance, is(instanceOf(Class1stLevel.Class2ndLevel.class))); } @Test public void whenCreateDeepInstanceIsCalledWithStackOfSize3_anInstanceOfThatObjectIsReturned() throws Throwable { Stack<Class<?>> classHierarchy = stackForClasses(Class1stLevel.Class2ndLevel.Class3rdLevel.class, Class1stLevel.Class2ndLevel.class, Class1stLevel.class); Object instance = ReflectionUtil.createDeepInstance(classHierarchy); assertThat(instance, is(notNullValue())); assertThat(instance, is(instanceOf(Class1stLevel.Class2ndLevel.Class3rdLevel.class))); } @Test public void whenCreateDeepInstanceIsCalledWithMemberClassOnly_anExceptionWillBeRaised() throws Throwable { thrown.expect(InstantiationException.class); Stack<Class<?>> classHierarchy = stackForClasses(Class1stLevel.Class2ndLevel.Class3rdLevel.class); Object instance = ReflectionUtil.createDeepInstance(classHierarchy); } @Test public void whenCreateDeepInstanceIsCalledWithInconsistentClassHierarchy_anExceptionWillBeRaised() throws Throwable { thrown.expect(NoSuchMethodException.class); Stack<Class<?>> classHierarchy = stackForClasses(Class1stLevel.Class2ndLevel.Class3rdLevel.class, Class1stLevel.class); Object instance = ReflectionUtil.createDeepInstance(classHierarchy); } }