diff --git a/binding/httpclient/src/test/java/io/tracee/outbound/httpclient/TraceeHttpClientDecoratorTest.java b/binding/httpclient/src/test/java/io/tracee/outbound/httpclient/TraceeHttpClientDecoratorTest.java index 18a44a8d..fe3e9cd0 100644 --- a/binding/httpclient/src/test/java/io/tracee/outbound/httpclient/TraceeHttpClientDecoratorTest.java +++ b/binding/httpclient/src/test/java/io/tracee/outbound/httpclient/TraceeHttpClientDecoratorTest.java @@ -1,6 +1,7 @@ package io.tracee.outbound.httpclient; +import io.tracee.DelegationTestUtil; import io.tracee.SimpleTraceeBackend; import io.tracee.TraceeBackend; import io.tracee.TraceeConstants; @@ -15,6 +16,7 @@ import java.util.Arrays; import java.util.Map; +import static io.tracee.DelegationTestUtil.assertDelegationToSpy; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; @@ -58,4 +60,12 @@ public void testContextParsedFromResponse() throws IOException { verify(transportSerializationMock).parse(eq(Arrays.asList("foo=bar"))); verify(backendMock).putAll(Mockito.anyMapOf(String.class, String.class)); } + + @Test + public void shouldDelegateAllPublicMethods() { + final HttpClient client = mock(HttpClient.class); + final HttpClient wrappedClient = TraceeHttpClientDecorator.wrap(client); + + assertDelegationToSpy(client).by(wrappedClient).ignore("executeMethod").verify(); + } } diff --git a/binding/jms/src/main/java/io/tracee/jms/out/TraceeMessageProducer.java b/binding/jms/src/main/java/io/tracee/jms/out/TraceeMessageProducer.java index 39c9f0b8..ef4bf339 100644 --- a/binding/jms/src/main/java/io/tracee/jms/out/TraceeMessageProducer.java +++ b/binding/jms/src/main/java/io/tracee/jms/out/TraceeMessageProducer.java @@ -12,7 +12,7 @@ import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncDispatch; -public final class TraceeMessageProducer implements MessageProducer { +public class TraceeMessageProducer implements MessageProducer { private final MessageProducer delegate; diff --git a/binding/jms/src/test/java/io/tracee/jms/out/TestMessageDelegation.java b/binding/jms/src/test/java/io/tracee/jms/out/TestMessageDelegation.java new file mode 100644 index 00000000..02996ecf --- /dev/null +++ b/binding/jms/src/test/java/io/tracee/jms/out/TestMessageDelegation.java @@ -0,0 +1,33 @@ +package io.tracee.jms.out; + +import io.tracee.DelegationTestUtil; +import org.junit.Test; + +import javax.jms.MessageProducer; +import javax.jms.QueueSender; +import javax.jms.TopicPublisher; + +import static org.mockito.Mockito.mock; + +public class TestMessageDelegation { + + @Test + public void delegateTraceeMessageProducerToMessageProducer() { + final MessageProducer messageProducer = mock(MessageProducer.class); + DelegationTestUtil.assertDelegationToSpy(messageProducer).by(new TraceeMessageProducer(messageProducer)).verify(); + } + + @Test + public void delegateTraceeMessageProducerToMessageQueueSender() { + final QueueSender queueSender = mock(QueueSender.class); + final TraceeMessageProducer traceeMessageProducer = new TraceeMessageProducer(queueSender); + DelegationTestUtil.assertDelegationToSpy(queueSender).by(new TraceeQueueSender(traceeMessageProducer, queueSender)).verify(); + } + + @Test + public void delegateTraceeTopicPublisherToTopicPublisher() { + final TopicPublisher topicPublisher = mock(TopicPublisher.class); + final TraceeTopicPublisher unit = new TraceeTopicPublisher(new TraceeMessageProducer(topicPublisher), topicPublisher); + DelegationTestUtil.assertDelegationToSpy(topicPublisher).by(unit).verify(); + } +} diff --git a/testhelper/pom.xml b/testhelper/pom.xml index 41a2fc98..d9422d02 100755 --- a/testhelper/pom.xml +++ b/testhelper/pom.xml @@ -19,6 +19,18 @@ tracee-api 0.7.0-SNAPSHOT + + org.mockito + mockito-core + ${mockito.version} + compile + + + org.hamcrest + hamcrest-core + ${hamcrest.version} + compile + @@ -30,7 +42,20 @@ true + + maven-enforcer-plugin + + + enforce + + enforce + + + true + + + + - diff --git a/testhelper/src/main/java/io/tracee/DelegationTestUtil.java b/testhelper/src/main/java/io/tracee/DelegationTestUtil.java new file mode 100644 index 00000000..00fdd9da --- /dev/null +++ b/testhelper/src/main/java/io/tracee/DelegationTestUtil.java @@ -0,0 +1,116 @@ +package io.tracee; + +import org.mockito.Mockito; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.mockito.Mockito.mock; + +public final class DelegationTestUtil { + + private static final Set BLACKLIST_METHOD = Collections.unmodifiableSet(new HashSet(Arrays.asList( + "class$", "finalize", "equals", "hashCode", "toString", "clone", "newInstance" + ))); + + public static Delegation assertDelegationToSpy(I innerObj) { + return new Delegation(innerObj); + } + + public static class Delegation { + private final I innerObj; + private W wrapperObj; + private final Set ignoreMethods = new HashSet(); + + Delegation(I innerObj) { + this.innerObj = innerObj; + } + + public Delegation by(final W wrapperObj) { + this.wrapperObj = wrapperObj; + return this; + } + + public Delegation ignore(String methodName) { + ignoreMethods.add(methodName); + return this; + } + + public void verify() { + if(!Mockito.mockingDetails(innerObj).isMock()) { + throw new IllegalStateException("Inner object is no Mockito mock!"); + } + if(Mockito.mockingDetails(wrapperObj).isMock()) { + throw new IllegalStateException("Wrapper objecgt should be real class with mocked inner object inside"); + } + + String errorMsg = ""; + try { + final Method[] wrapperMethods = wrapperObj.getClass().getDeclaredMethods(); + final Map innerMethods = new HashMap(); + for (Method innerMethod : innerObj.getClass().getDeclaredMethods()) { + if (Modifier.isPublic(innerMethod.getModifiers())) { + innerMethods.put(innerMethod.getName() + " :: " + paramsToStr(innerMethod.getParameterTypes()), innerMethod); + } + } + + for (Method wrapperMethod : wrapperMethods) { + if (innerMethods.containsKey(wrapperMethod.getName() + " :: " + paramsToStr(wrapperMethod.getParameterTypes())) + && !BLACKLIST_METHOD.contains(wrapperMethod.getName()) + && !ignoreMethods.contains(wrapperMethod.getName())) { + errorMsg = "Method not delegated: " + wrapperMethod.getName(); + + final Object[] arguments = generateMockedParams(wrapperMethod); + + wrapperMethod.invoke(wrapperObj, arguments); + innerMethods.get(wrapperMethod.getName() + " :: " + paramsToStr(wrapperMethod.getParameterTypes())).invoke(Mockito.verify(innerObj), arguments); + } + } + } catch (Exception e) { + throw new RuntimeException(errorMsg + "\n" + e.getMessage(), e); + } + } + } + + private static Object[] generateMockedParams(Method wrapperMethod) { + final Class[] parameterTypes = wrapperMethod.getParameterTypes(); + final List arguments = new ArrayList(); + for (Class parameterType : parameterTypes) { + if ("boolean".equals(parameterType.getName())) { + arguments.add(Boolean.FALSE); + } else if ("int".equals(parameterType.getName())) { + arguments.add(0); + } else if ("long".equals(parameterType.getName())) { + arguments.add(0L); + } else if (parameterType == String.class) { + arguments.add(""); + } else { + arguments.add(mock(parameterType)); + } + } + return arguments.toArray(new Object[arguments.size()]); + } + + private static String paramsToStr(Class[] parameterTypes) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0, parameterTypesLength = parameterTypes.length; i < parameterTypesLength; i++) { + Class type = parameterTypes[i]; + sb.append(type.getName()); + if (i < (parameterTypesLength - 1)) { + sb.append(", "); + } + } + return sb.toString(); + } + + private DelegationTestUtil() { + } +} diff --git a/testhelper/src/test/java/io/tracee/DelegationTestUtilTest.java b/testhelper/src/test/java/io/tracee/DelegationTestUtilTest.java new file mode 100644 index 00000000..8c55a1ef --- /dev/null +++ b/testhelper/src/test/java/io/tracee/DelegationTestUtilTest.java @@ -0,0 +1,104 @@ +package io.tracee; + +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class DelegationTestUtilTest { + + @Rule + public ExpectedException exeptionRule = ExpectedException.none(); + + @Test + public void shouldFindAllDelegations() { + final DelegationClass delegate = Mockito.spy(new DelegationClass()); + final RightWrapper rightWrapper = new RightWrapper(delegate); + DelegationTestUtil.assertDelegationToSpy(delegate).by(rightWrapper).verify(); + assertThat(delegate.getInvotionCount(), is(3)); + } + + @Test + public void shouldFindErrorsInDelegate() { + exeptionRule.expect(RuntimeException.class); + exeptionRule.expectMessage("Method not delegated: getInteger"); + + final DelegationClass delegate = Mockito.spy(new DelegationClass()); + final WrongWrapper rightWrapper = new WrongWrapper(delegate); + DelegationTestUtil.assertDelegationToSpy(delegate).by(rightWrapper).verify(); + } + + public class DelegationClass { + + private int invocationCount = 0; + + public int getInvotionCount() { + return invocationCount; + } + + public void setString(String str) { + invocationCount++; + } + + public void setInteger(int i) { + invocationCount++; + } + + public int getInteger() { + invocationCount++; + return 1; + } + } + + public class WrongWrapper extends DelegationClass { + + private final DelegationClass delegate; + + public WrongWrapper(DelegationClass delegate) { + this.delegate = delegate; + } + + @Override + public void setString(String str) { + delegate.setString(str); + } + + @Override + public int getInteger() { + return -1; + } + + @Override + public void setInteger(int i) { + delegate.setInteger(i); + } + } + + public class RightWrapper extends DelegationClass { + + private final DelegationClass delegate; + + public RightWrapper(DelegationClass delegate) { + this.delegate = delegate; + } + + @Override + public void setString(String str) { + delegate.setString(str); + } + + @Override + public int getInteger() { + return delegate.getInteger(); + } + + @Override + public void setInteger(int i) { + delegate.setInteger(i); + } + } +}