package com.lexicalscope.fluentreflection.endtoend; import static com.lexicalscope.fluentreflection.FluentReflection.type; import static com.lexicalscope.fluentreflection.ReflectionMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import com.lexicalscope.fluentreflection.IllegalArgumentRuntimeException; public class TestReflectedClassInstanceMethod { @Rule public final ExpectedException exception = ExpectedException.none(); public static class ClassWithInstanceMethods { private boolean called; private boolean objectCalled; private boolean stringCalled; private boolean stringAndIntegerCalled; public void simpleMethod() { called = true; } public int methodWithReturnValue() { return 42; } public void methodWithOneArgument(final String string) { stringCalled = true; } public void methodWithTwoArguments(final String string, final Integer integer) { stringAndIntegerCalled = true; } public void methodWithOneArgument(final Object object) { objectCalled = true; } } private final ClassWithInstanceMethods instance = new ClassWithInstanceMethods(); @Test public void simpleMethodCanBeCalled() { type(ClassWithInstanceMethods.class).method(hasName("simpleMethod")).call(instance); assertThat(instance.called, equalTo(true)); } @Test public void callingMethodWithReturnValueReturnsValue() { final Integer result = (Integer) type(ClassWithInstanceMethods.class) .method(hasName("methodWithReturnValue")) .call(instance).value(); assertThat(result, equalTo(42)); } @Test public void canCallMethodWithOneArgumentIfMultipleMatches() { type(ClassWithInstanceMethods.class).method(hasName("methodWithOneArgument")).call(instance, "string"); assertThat(instance.stringCalled || instance.objectCalled, equalTo(true)); } @Test public void methodWithTwoArgumentsCanBeCalled() { type(ClassWithInstanceMethods.class).method(hasName("methodWithTwoArguments")).call( instance, "string", 42); assertThat(instance.stringAndIntegerCalled, equalTo(true)); } @Test public void methodWithTwoArgumentsHasCorrectArgumentCount() { assertThat( type(ClassWithInstanceMethods.class).method(hasName("methodWithTwoArguments")).argCount(), equalTo(2)); } @SuppressWarnings("unchecked") @Test public void instanceMethodArgumentTypeIsCorrect() throws Exception { assertThat( type(ClassWithInstanceMethods.class).method(hasName("methodWithTwoArguments")).args(), contains( reflectingOn(String.class), reflectingOn(Integer.class))); } @Test public void callingInstanceMethodWithoutInstanceFails() { exception.expect(IllegalArgumentException.class); exception.expectMessage("target instance must be specified"); type(ClassWithInstanceMethods.class).method(hasName("simpleMethod")).call(); } @Test public void callingInstanceMethodWithWrongInstanceType() { exception.expect(IllegalArgumentRuntimeException.class); exception.expectMessage(containsString("not an instance of declaring class")); type(ClassWithInstanceMethods.class).method(hasName("simpleMethod")).call(new Object()); } }