From c27d20817e996891cedd0932b08c14c6eb9cc1fd Mon Sep 17 00:00:00 2001 From: Iwein Fuld Date: Fri, 24 Jul 2009 14:00:31 +0000 Subject: [PATCH] INT-144 moved test project into trunk, and some related improvements --- .../.classpath | 57 +++++++ org.springframework.integration.test/.project | 23 +++ .../.springBeans | 13 ++ .../build.xml | 8 + org.springframework.integration.test/ivy.xml | 30 ++++ .../integration/test/TestMessage.java | 31 ++++ .../test/matcher/HeaderMatcher.java | 115 ++++++++++++++ .../test/matcher/MapContentMatchers.java | 143 ++++++++++++++++++ .../test/matcher/MockitoMessageMatchers.java | 89 +++++++++++ .../test/matcher/PayloadMatcher.java | 95 ++++++++++++ .../integration/test/util/TestUtils.java | 143 ++++++++++++++++++ .../test/matcher/HeaderMatcherTests.java | 142 +++++++++++++++++ .../test/matcher/MapContainsTests.java | 104 +++++++++++++ .../matcher/MockitoMessageMatchersTests.java | 94 ++++++++++++ .../test/matcher/PayloadMatcherTests.java | 72 +++++++++ .../template.mf | 10 ++ 16 files changed, 1169 insertions(+) create mode 100644 org.springframework.integration.test/.classpath create mode 100644 org.springframework.integration.test/.project create mode 100644 org.springframework.integration.test/.springBeans create mode 100644 org.springframework.integration.test/build.xml create mode 100644 org.springframework.integration.test/ivy.xml create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/TestMessage.java create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/HeaderMatcher.java create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MapContentMatchers.java create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MockitoMessageMatchers.java create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/PayloadMatcher.java create mode 100644 org.springframework.integration.test/src/main/java/org/springframework/integration/test/util/TestUtils.java create mode 100644 org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/HeaderMatcherTests.java create mode 100644 org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MapContainsTests.java create mode 100644 org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MockitoMessageMatchersTests.java create mode 100644 org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/PayloadMatcherTests.java create mode 100644 org.springframework.integration.test/template.mf diff --git a/org.springframework.integration.test/.classpath b/org.springframework.integration.test/.classpath new file mode 100644 index 0000000000..01b4aa119b --- /dev/null +++ b/org.springframework.integration.test/.classpath @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.springframework.integration.test/.project b/org.springframework.integration.test/.project new file mode 100644 index 0000000000..b588dbf073 --- /dev/null +++ b/org.springframework.integration.test/.project @@ -0,0 +1,23 @@ + + + org.springframework.integration.test + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + + diff --git a/org.springframework.integration.test/.springBeans b/org.springframework.integration.test/.springBeans new file mode 100644 index 0000000000..51529914c5 --- /dev/null +++ b/org.springframework.integration.test/.springBeans @@ -0,0 +1,13 @@ + + + 1 + + + + + + + + + + diff --git a/org.springframework.integration.test/build.xml b/org.springframework.integration.test/build.xml new file mode 100644 index 0000000000..d4b00fd40e --- /dev/null +++ b/org.springframework.integration.test/build.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.springframework.integration.test/ivy.xml b/org.springframework.integration.test/ivy.xml new file mode 100644 index 0000000000..7fd4f519c9 --- /dev/null +++ b/org.springframework.integration.test/ivy.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/TestMessage.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/TestMessage.java new file mode 100644 index 0000000000..baf3fd52f1 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/TestMessage.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.test; + +import org.springframework.integration.message.StringMessage; + +/** + * @author Mark Fisher + */ +@SuppressWarnings("serial") +public class TestMessage extends StringMessage { + + public TestMessage(String payload) { + super("test"); + } + +} diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/HeaderMatcher.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/HeaderMatcher.java new file mode 100644 index 0000000000..6bef0a28e2 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/HeaderMatcher.java @@ -0,0 +1,115 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import java.util.Map; + +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.junit.Assert; +import org.junit.internal.matchers.TypeSafeMatcher; +import org.springframework.integration.core.Message; +import org.springframework.integration.core.MessageHeaders; + +/** + *

Are the {@link MessageHeaders} of a {@link Message} containing any entry + * or multiple that match?

+ * + * + *

+ * For example using {@link Assert#assertThat(Object, Matcher)} for a single + * entry:

+ * + *
+ * ANY_HEADER_KEY = "foo";
+ * ANY_HEADER_VALUE = "bar";
+ * assertThat(message, hasEntry(ANY_HEADER_KEY, ANY_HEADER_VALUE));
+ * assertThat(message, hasEntry(ANY_HEADER_KEY, is(String.class)));
+ * assertThat(message, hasEntry(ANY_HEADER_KEY, notNullValue()));
+ * assertThat(message, hasEntry(ANY_HEADER_KEY, is(ANY_HEADER_VALUE)));
+ * 
+ * + *

For multiple entries to match all:

+ * + *
+ * Map<String, Object> expectedInHeaderMap = new HashMap<String, Object>();
+ * expectedInHeaderMap.put(ANY_HEADER_KEY, ANY_HEADER_VALUE);
+ * expectedInHeaderMap.put(OTHER_HEADER_KEY, is(OTHER_HEADER_VALUE));
+ * assertThat(message, HeaderMatcher.hasAllEntries(expectedInHeaderMap));
+ * 
+ * + *

+ * For a single key:

+ * + *
+ * ANY_HEADER_KEY = "foo";
+ * assertThat(message, HeaderMatcher.hasKey(ANY_HEADER_KEY));
+ * 
+ * + * + * @author Alex Peters + * @author Iwein Fuld + * + */ +public class HeaderMatcher extends TypeSafeMatcher> { + + private final Matcher matcher; + + /** + * @param matcher + */ + HeaderMatcher(Matcher matcher) { + super(); + this.matcher = matcher; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean matchesSafely(Message item) { + return matcher.matches(item.getHeaders()); + } + + /** + * {@inheritDoc} + */ + public void describeTo(Description description) { + description.appendText("a Message with Headers containing ").appendDescriptionOf(matcher); + + } + + @Factory + public static Matcher> hasHeader(String key, T value) { + return new HeaderMatcher(MapContentMatchers.hasEntry(key, value)); + } + + @Factory + public static Matcher> hasHeader(String key, Matcher valueMatcher) { + return new HeaderMatcher(MapContentMatchers.hasEntry(key, valueMatcher)); + } + + @Factory + public static Matcher> hasHeaderKey(String key) { + return new HeaderMatcher(MapContentMatchers.hasKey(key)); + } + + @Factory + public static Matcher> hasAllHeaders(Map entries) { + return new HeaderMatcher(MapContentMatchers.hasAllEntries(entries)); + } +} \ No newline at end of file diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MapContentMatchers.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MapContentMatchers.java new file mode 100644 index 0000000000..2e0c17c532 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MapContentMatchers.java @@ -0,0 +1,143 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import static org.hamcrest.CoreMatchers.anything; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.hamcrest.core.AllOf; +import org.hamcrest.core.IsEqual; +import org.junit.internal.matchers.TypeSafeMatcher; + +/** + * Matchers that examine the contents of a {@link Map}. + *

+ * It is possible to match a single entry by value or matcher like this: + *

+ * + *
+ * assertThat(map, hasEntry(SOME_KEY, is(SOME_VALUE)));
+ * assertThat(map, hasEntry(SOME_KEY, is(String.class)));
+ * assertThat(map, hasEntry(SOME_KEY, notNullValue()));
+ * 
+ * + *

+ * It's also possible to match multiple entries in a map: + *

+ * + *
+ * Map<String, Object> expectedInMap = new HashMap<String, Object>();
+ * expectedInMap.put(SOME_KEY, SOME_VALUE);
+ * expectedInMap.put(OTHER_KEY, is(OTHER_VALUE));
+ * assertThat(map, hasAllEntries(expectedInMap));
+ * 
+ * + *

If you only need to verify the existence of a key:

+ * + *
+ * assertThat(map, hasKey(SOME_KEY));
+ * 
+ * + * @author Alex Peters + * @author Iwein Fuld + * + */ +public class MapContentMatchers extends + TypeSafeMatcher> { + + private final T key; + + private final Matcher valueMatcher; + + /** + * @param key + * @param value + */ + MapContentMatchers(T key, V value) { + this(key, IsEqual.equalTo(value)); + } + + /** + * @param key + * @param valueMatcher + */ + MapContentMatchers(T key, Matcher valueMatcher) { + super(); + this.key = key; + this.valueMatcher = valueMatcher; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean matchesSafely(Map item) { + return item.containsKey(key) && valueMatcher.matches(item.get(key)); + } + + /** + * {@inheritDoc} + */ +// @Override + public void describeTo(Description description) { + description.appendText("an entry with key ").appendValue(key) + .appendText(" and value matching ").appendDescriptionOf( + valueMatcher); + + } + + @Factory + public static Matcher> hasEntry(T key, + V value) { + return new MapContentMatchers(key, value); + } + + @Factory + public static Matcher> hasEntry(T key, + Matcher valueMatcher) { + return new MapContentMatchers(key, valueMatcher); + } + + @Factory + @SuppressWarnings("unchecked") + public static Matcher> hasKey(T key) { + return new MapContentMatchers(key, (Matcher) anything("any Value")); + } + + @Factory + @SuppressWarnings("unchecked") + public static Matcher> hasAllEntries( + Map entries) { + List>> matchers = new ArrayList>>( + entries.size()); + for (Map.Entry entry : entries.entrySet()) { + final V value = entry.getValue(); + if (value instanceof Matcher) { + matchers.add(hasEntry(entry.getKey(), (Matcher) value)); + } + else { + matchers.add(hasEntry(entry.getKey(), value)); + } + } + return AllOf.allOf(matchers); + } +} diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MockitoMessageMatchers.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MockitoMessageMatchers.java new file mode 100644 index 0000000000..d89c929874 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/MockitoMessageMatchers.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import static org.mockito.Matchers.argThat; +import static org.springframework.integration.test.matcher.HeaderMatcher.hasHeader; +import static org.springframework.integration.test.matcher.PayloadMatcher.hasPayload; + +import java.util.Map; + +import org.hamcrest.Matcher; +import org.mockito.Mockito; +import org.springframework.integration.core.Message; + +/** + *

Mockito matcher factory for {@link Message} matcher creation.

+ *

+ * This class contains expressive factory methods for the most common Mockito + * matchers needed when matching {@link Message}s. Any Hamcrest matcher can be + * used in Mockito through {@link Mockito#argThat(Matcher)}. + * + *

Example usage:

+ *

+ * With {@link Mockito#verify(Object)}: + *

+ * + *
+ * @Mock
+ * MessageHandler handler;
+ * ...
+ * handler.handleMessage(message);
+ * verify(handler).handleMessage(messageWithPayload(SOME_PAYLOAD));
+ * verify(handler).handleMessage(messageWithPayload(is(SOME_CLASS)));
+ * 
+ *

+ * With {@link Mockito#when(Object)}: + *

+ *
+ * ...
+ * when(channel.send(messageWithPayload(SOME_PAYLOAD))).thenReturn(true);
+ * assertThat(channel.send(message), is(true));
+ * 
+ * + * @author Alex Peters + * @author Iwein Fuld + * + */ +public class MockitoMessageMatchers { + + @SuppressWarnings("unchecked") + public static Message messageWithPayload(Matcher payloadMatcher) { + return (Message) argThat(hasPayload(payloadMatcher)); + } + + @SuppressWarnings("unchecked") + public static Message messageWithPayload(T payload) { + return (Message) argThat(hasPayload(payload)); + } + + public static Message messageWithHeaderEntry(String key, Object value) { + return argThat(hasHeader(key, value)); + } + + public static Message messageWithHeaderEntry(String key) { + return argThat(HeaderMatcher.hasHeaderKey(key)); + } + + public static Message messageWithHeaderEntry(String key, + Matcher valueMatcher) { + return argThat(HeaderMatcher. hasHeader(key, valueMatcher)); + } + + public static Message messageWithHeaderEntries(Map entries) { + return argThat(HeaderMatcher.hasAllHeaders(entries)); + } +} diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/PayloadMatcher.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/PayloadMatcher.java new file mode 100644 index 0000000000..14352628d8 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/matcher/PayloadMatcher.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.hamcrest.core.IsEqual; +import org.junit.Assert; +import org.junit.internal.matchers.TypeSafeMatcher; +import org.springframework.integration.core.Message; + +/** + *

Is the payload of a {@link Message} equal to a given value or is matching + * a given matcher?

+ * + *

+ * A Junit example using {@link Assert#assertThat(Object, Matcher)} could look + * like this to test a payload value:

+ * + *
+ * ANY_PAYLOAD = new BigDecimal("1.123");
+ * Message<BigDecimal message = MessageBuilder.withPayload(ANY_PAYLOAD).build();
+ * assertThat(message, hasPayload(ANY_PAYLOjAD));
+ * 
+ * + *

+ * An example using {@link Assert#assertThat(Object, Matcher)} delegating to + * another {@link Matcher}.

+ * + *
+ * ANY_PAYLOAD = new BigDecimal("1.123");
+ * assertThat(message, PayloadMatcher.hasPayload(is(BigDecimal.class)));
+ * assertThat(message, PayloadMatcher.hasPayload(notNullValue()));
+ * assertThat(message, not((PayloadMatcher.hasPayload(is(String.class))))); *
+ * 
+ * + * + * + * @author Alex Peters + * @author Iwein Fuld + * + */ +public class PayloadMatcher extends TypeSafeMatcher> { + + private final Matcher matcher; + + /** + * @param matcher + */ + PayloadMatcher(Matcher matcher) { + super(); + this.matcher = matcher; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean matchesSafely(Message message) { + return matcher.matches(message.getPayload()); + } + + /** + * {@inheritDoc} + */ + //@Override + public void describeTo(Description description) { + description.appendText("a Message with payload: ").appendDescriptionOf(matcher); + + } + + @Factory + public static Matcher> hasPayload(T payload) { + return new PayloadMatcher(IsEqual.equalTo(payload)); + } + + @Factory + public static Matcher> hasPayload(Matcher payloadMatcher) { + return new PayloadMatcher(payloadMatcher); + } +} \ No newline at end of file diff --git a/org.springframework.integration.test/src/main/java/org/springframework/integration/test/util/TestUtils.java b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/util/TestUtils.java new file mode 100644 index 0000000000..c6d8c5ea44 --- /dev/null +++ b/org.springframework.integration.test/src/main/java/org/springframework/integration/test/util/TestUtils.java @@ -0,0 +1,143 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.test.util; + +import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; + +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.integration.core.MessageChannel; +import org.springframework.integration.endpoint.AbstractEndpoint; +import org.springframework.integration.endpoint.AbstractPollingEndpoint; +import org.springframework.integration.scheduling.IntervalTrigger; +import org.springframework.integration.scheduling.SimpleTaskScheduler; +import org.springframework.integration.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.Assert; + +/** + * @author Mark Fisher + */ +public abstract class TestUtils { + + public static Object getPropertyValue(Object root, String propertyPath) { + Object value = null; + DirectFieldAccessor accessor = new DirectFieldAccessor(root); + String[] tokens = propertyPath.split("\\."); + for (int i = 0; i < tokens.length; i++) { + value = accessor.getPropertyValue(tokens[i]); + if (value != null) { + accessor = new DirectFieldAccessor(value); + } + else if (i == tokens.length - 1) { + return null; + } + else { + throw new IllegalArgumentException( + "intermediate property '" + tokens[i] + "' is null"); + } + } + return value; + } + + @SuppressWarnings("unchecked") + public static T getPropertyValue(Object root, String propertyPath, Class type) { + Object value = getPropertyValue(root, propertyPath); + Assert.isAssignable(type, value.getClass()); + return (T) value; + } + + public static TestApplicationContext createTestApplicationContext() { + TestApplicationContext context = new TestApplicationContext(); + registerBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, createTaskScheduler(10), context); + return context; + } + + public static TaskScheduler createTaskScheduler(int poolSize) { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(poolSize); + executor.setRejectedExecutionHandler(new CallerRunsPolicy()); + executor.afterPropertiesSet(); + return new SimpleTaskScheduler(executor); + } + + private static void registerBean(String beanName, Object bean, BeanFactory beanFactory) { + Assert.notNull(beanName, "bean name must not be null"); + ConfigurableListableBeanFactory configurableListableBeanFactory = null; + if (beanFactory instanceof ConfigurableListableBeanFactory) { + configurableListableBeanFactory = (ConfigurableListableBeanFactory) beanFactory; + } + else if (beanFactory instanceof GenericApplicationContext) { + configurableListableBeanFactory = ((GenericApplicationContext) beanFactory).getBeanFactory(); + } + if (bean instanceof BeanNameAware) { + ((BeanNameAware) bean).setBeanName(beanName); + } + if (bean instanceof BeanFactoryAware) { + ((BeanFactoryAware) bean).setBeanFactory(beanFactory); + } + if (bean instanceof InitializingBean) { + try { + ((InitializingBean) bean).afterPropertiesSet(); + } + catch (Exception e) { + throw new FatalBeanException("failed to register bean with test context", e); + } + } + configurableListableBeanFactory.registerSingleton(beanName, bean); + } + + + public static class TestApplicationContext extends GenericApplicationContext { + + private TestApplicationContext() { + super(); + } + + public void registerChannel(String channelName, MessageChannel channel) { + if (channel.getName() != null) { + if (channelName == null) { + Assert.notNull(channel.getName(), "channel name must not be null"); + channelName = channel.getName(); + } + else { + Assert.isTrue(channel.getName().equals(channelName), + "channel name has already been set with a conflicting value"); + } + } + registerBean(channelName, channel, this); + } + + public void registerEndpoint(String endpointName, AbstractEndpoint endpoint) { + if (endpoint instanceof AbstractPollingEndpoint) { + DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint); + if (accessor.getPropertyValue("trigger") == null) { + ((AbstractPollingEndpoint) endpoint).setTrigger(new IntervalTrigger(10)); + } + } + registerBean(endpointName, endpoint, this); + } + } + +} diff --git a/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/HeaderMatcherTests.java b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/HeaderMatcherTests.java new file mode 100644 index 0000000000..50adfc5c93 --- /dev/null +++ b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/HeaderMatcherTests.java @@ -0,0 +1,142 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.test.matcher; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.springframework.integration.test.matcher.HeaderMatcher.*; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.integration.core.Message; +import org.springframework.integration.message.MessageBuilder; + +/** + * @author Alex Peters + * @author Iwein Fuld + * + */ +public class HeaderMatcherTests { + + static final String UNKNOWN_KEY = "unknownKey"; + + static final String ANY_HEADER_VALUE = "bar"; + + static final String ANY_HEADER_KEY = "test.foo"; + + static final String ANY_PAYLOAD = "bla"; + + static final String OTHER_HEADER_KEY = "test.number"; + + static final Integer OTHER_HEADER_VALUE = Integer.valueOf(123); + + Message message; + + @Before + public void setUp() { + message = MessageBuilder.withPayload(ANY_PAYLOAD).setHeader(ANY_HEADER_KEY, + ANY_HEADER_VALUE).setHeader(OTHER_HEADER_KEY, OTHER_HEADER_VALUE).build(); + } + + @Test + public void hasEntry_withValidKeyValue_matches() throws Exception { + assertThat(message, hasHeader(ANY_HEADER_KEY, ANY_HEADER_VALUE)); + assertThat(message, hasHeader(OTHER_HEADER_KEY, OTHER_HEADER_VALUE)); + } + + @Test + public void hasEntry_withUnknownKey_notMatching() throws Exception { + assertThat(message, not(hasHeader("test.unknown", ANY_HEADER_VALUE))); + } + + @Test + public void hasEntry_withValidKeyAndMatcherValue_matches() throws Exception { + assertThat(message, hasHeader(ANY_HEADER_KEY, is(String.class))); + assertThat(message, hasHeader(ANY_HEADER_KEY, notNullValue())); + assertThat(message, hasHeader(ANY_HEADER_KEY, is(ANY_HEADER_VALUE))); + } + + @Test + public void hasEntry_withValidKeyAndMatcherValue_notMatching() throws Exception { + assertThat(message, not(hasHeader(ANY_HEADER_KEY, is(Integer.class)))); + } + + @Test + public void hasKey_withValidKey_matches() throws Exception { + assertThat(message, hasHeaderKey(ANY_HEADER_KEY)); + assertThat(message, hasHeaderKey(OTHER_HEADER_KEY)); + } + + @Test + public void hasKey_withInvalidKey_notMatching() throws Exception { + assertThat(message, not(hasHeaderKey(UNKNOWN_KEY))); + } + + @Test + public void hasAllEntries_withMessageHeader_matches() throws Exception { + Map expectedInHeaderMap = message.getHeaders(); + assertThat(message, hasAllHeaders(expectedInHeaderMap)); + } + + @Test + public void hasAllEntries_withValidKeyValueOrMatcherValue_matches() throws Exception { + Map expectedInHeaderMap = new HashMap(); + expectedInHeaderMap.put(ANY_HEADER_KEY, ANY_HEADER_VALUE); + expectedInHeaderMap.put(OTHER_HEADER_KEY, is(OTHER_HEADER_VALUE)); + assertThat(message, hasAllHeaders(expectedInHeaderMap)); + } + + @Test + public void hasAllEntries_withInvalidValidKeyValueOrMatcherValue_notMatching() throws Exception { + Map expectedInHeaderMap = new HashMap(); + expectedInHeaderMap.put(ANY_HEADER_KEY, ANY_HEADER_VALUE); // valid + expectedInHeaderMap.put(UNKNOWN_KEY, not(nullValue())); // fails + assertThat(message, not(hasAllHeaders(expectedInHeaderMap))); + expectedInHeaderMap.remove(UNKNOWN_KEY); + expectedInHeaderMap.put(OTHER_HEADER_KEY, ANY_HEADER_VALUE); // fails + } + + @Test + public void readableException_singleHeader() throws Exception { + try { + assertThat(message, hasHeader("corn", "bread")); + } + catch (AssertionError ae){ + assertTrue(ae.getMessage().contains("Expected: a Message with Headers containing ")); + } + } + + @Test + public void readableException_allHeaders() throws Exception { + try { + Map entries = new HashMap(); + entries.put("corn", "bread"); + entries.put("chocolate", "pudding"); + assertThat(message, hasAllHeaders(entries)); + } + catch (AssertionError ae){ + assertTrue(ae.getMessage().contains("Expected: a Message with Headers containing ")); + } + } +} diff --git a/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MapContainsTests.java b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MapContainsTests.java new file mode 100644 index 0000000000..67f510eafe --- /dev/null +++ b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MapContainsTests.java @@ -0,0 +1,104 @@ +package org.springframework.integration.test.matcher; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.springframework.integration.test.matcher.MapContentMatchers.hasAllEntries; +import static org.springframework.integration.test.matcher.MapContentMatchers.hasEntry; +import static org.springframework.integration.test.matcher.MapContentMatchers.hasKey; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +/** + * @author Alex Peters + * + */ +public class MapContainsTests { + + static final String UNKNOWN_KEY = "unknownKey"; + + static final String SOME_VALUE = "bar"; + + static final String SOME_KEY = "test.foo"; + + static final String OTHER_KEY = "test.number"; + + static final Integer OTHER_VALUE = Integer.valueOf(123); + + private HashMap map; + + @Before + public void setUp() { + map = new HashMap(); + map.put(SOME_KEY, SOME_VALUE); + map.put(OTHER_KEY, OTHER_VALUE); + } + + @Test + public void hasKey_validKey_matching() throws Exception { + assertThat(map, hasKey(SOME_KEY)); + + } + + @Test + public void hasKey_unknownKey_notMatching() throws Exception { + assertThat(map, not(hasKey(UNKNOWN_KEY))); + } + + @Test + public void hasEntry_withValidKeyValue_matches() throws Exception { + assertThat(map, hasEntry(SOME_KEY, SOME_VALUE)); + assertThat(map, hasEntry(OTHER_KEY, OTHER_VALUE)); + } + + @Test + public void hasEntry_withUnknownKey_notMatching() throws Exception { + assertThat(map, not(hasEntry("test.unknown", SOME_VALUE))); + } + + @Test + public void hasEntry_withValidKeyAndMatcherValue_matches() throws Exception { + assertThat(map, hasEntry(SOME_KEY, is(String.class))); + assertThat(map, hasEntry(SOME_KEY, notNullValue())); + assertThat(map, hasEntry(SOME_KEY, is(SOME_VALUE))); + } + + @Test + public void hasEntry_withValidKeyAndMatcherValue_notMatching() throws Exception { + assertThat(map, not(hasEntry(SOME_KEY, is(Integer.class)))); + } + + @Test + public void hasEntry_withTypedValueMap_matches() throws Exception { + Map map = new HashMap(); + map.put("a", "b"); + map.put("c", "d"); + assertThat(map, hasEntry("a", "b")); + assertThat(map, not(hasEntry(SOME_KEY, is("a")))); + assertThat(map, hasAllEntries(map)); + } + + @Test + public void hasAllEntries_withValidKeyValueOrMatcherValue_matches() throws Exception { + Map expectedInHeaderMap = new HashMap(); + expectedInHeaderMap.put(SOME_KEY, SOME_VALUE); + expectedInHeaderMap.put(OTHER_KEY, is(OTHER_VALUE)); + assertThat(map, hasAllEntries(expectedInHeaderMap)); + } + + @Test + public void hasAllEntries_withInvalidValidKeyValueOrMatcherValue_notMatching() throws Exception { + Map expectedInHeaderMap = new HashMap(); + expectedInHeaderMap.put(SOME_KEY, SOME_VALUE); // valid + expectedInHeaderMap.put(UNKNOWN_KEY, not(nullValue())); // fails + assertThat(map, not(hasAllEntries(expectedInHeaderMap))); + expectedInHeaderMap.remove(UNKNOWN_KEY); + expectedInHeaderMap.put(OTHER_KEY, SOME_VALUE); // fails + } +} diff --git a/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MockitoMessageMatchersTests.java b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MockitoMessageMatchersTests.java new file mode 100644 index 0000000000..003c9d3da4 --- /dev/null +++ b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/MockitoMessageMatchersTests.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.integration.test.matcher.MockitoMessageMatchers.messageWithHeaderEntry; +import static org.springframework.integration.test.matcher.MockitoMessageMatchers.messageWithPayload; + +import java.util.Date; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent; +import org.mockito.runners.MockitoJUnit44Runner; +import org.springframework.integration.core.Message; +import org.springframework.integration.core.MessageChannel; +import org.springframework.integration.message.MessageBuilder; +import org.springframework.integration.message.MessageHandler; + +/** + * @author Alex Peters + * @author Iwein Fuld + * + */ +@RunWith(MockitoJUnit44Runner.class) +public class MockitoMessageMatchersTests { + + static final Date SOME_PAYLOAD = new Date(); + + static final String UNKNOWN_KEY = "unknownKey"; + + static final String SOME_HEADER_VALUE = "bar"; + + static final String SOME_HEADER_KEY = "test.foo"; + + @Mock + MessageHandler handler; + + @Mock + MessageChannel channel; + + Message message; + + @Before + public void setUp() { + message = MessageBuilder.withPayload(SOME_PAYLOAD).setHeader(SOME_HEADER_KEY, + SOME_HEADER_VALUE).build(); + } + + @Test + public void anyMatcher_withVerifyArgumentMatcherAndEqualPayload_matching() throws Exception { + handler.handleMessage(message); + verify(handler).handleMessage(messageWithPayload(SOME_PAYLOAD)); + verify(handler).handleMessage(messageWithPayload(is(Date.class))); + } + + @Test(expected = ArgumentsAreDifferent.class) + public void anyMatcher_withVerifyAndDifferentPayload_notMatching() throws Exception { + handler.handleMessage(message); + verify(handler).handleMessage(messageWithPayload(nullValue())); + } + + @Test + public void anyMatcher_withWhenArgumentMatcherAndEqualPayload_matching() throws Exception { + when(channel.send(messageWithPayload(SOME_PAYLOAD))).thenReturn(true); + assertThat(channel.send(message), is(true)); + } + + @Test + public void anyMatcher_withWhenAndDifferentPayload_notMatching() throws Exception { + when(channel.send(messageWithHeaderEntry(SOME_HEADER_KEY, is(Short.class)))).thenReturn(true); + assertThat(channel.send(message), is(false)); + } + +} diff --git a/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/PayloadMatcherTests.java b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/PayloadMatcherTests.java new file mode 100644 index 0000000000..74848f821a --- /dev/null +++ b/org.springframework.integration.test/src/test/java/org/springframework/integration/test/matcher/PayloadMatcherTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.test.matcher; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.springframework.integration.test.matcher.PayloadMatcher.hasPayload; + +import java.math.BigDecimal; + +import org.junit.Test; +import org.springframework.integration.core.Message; +import org.springframework.integration.message.MessageBuilder; + +/** + * @author Alex Peters + * @author Iwein Fuld + */ +public class PayloadMatcherTests { + + static final BigDecimal ANY_PAYLOAD = new BigDecimal("1.123"); + + Message message =MessageBuilder.withPayload(ANY_PAYLOAD).build();; + + @Test + public void hasPayload_withEqualValue_matches() throws Exception { + assertThat(message, hasPayload(new BigDecimal("1.123"))); + } + + @Test + public void hasPayload_withNotEqualValue_notMatching() throws Exception { + assertThat(message, not(hasPayload(new BigDecimal("456")))); + } + + @Test + public void hasPayload_withMatcher_matches() throws Exception { + assertThat(message, + hasPayload(is(BigDecimal.class))); + assertThat(message, hasPayload(notNullValue())); + } + + @Test + public void hasPayload_withNotMatchingMatcher_notMatching() + throws Exception { + assertThat(message, not((hasPayload(is(String.class))))); + } + + @Test + public void readableException() throws Exception { + try { + assertThat(message, hasPayload("woot")); + } catch(AssertionError ae){ + assertTrue(ae.getMessage().contains("Expected: a Message with payload: ")); + } + } +} diff --git a/org.springframework.integration.test/template.mf b/org.springframework.integration.test/template.mf new file mode 100644 index 0000000000..3b777a6953 --- /dev/null +++ b/org.springframework.integration.test/template.mf @@ -0,0 +1,10 @@ +Bundle-SymbolicName: org.springframework.integration.test +Bundle-Name: Spring Integration Test Support +Bundle-Vendor: SpringSource +Bundle-ManifestVersion: 2 +Import-Template: + org.springframework.*;version="[2.5.6.A, 3.1.0)", + org.springframework.integration.*;version="[1.0.3, 1.0.4)", + org.junit.*;version="[4.6.0, 4.7.0)", + org.mockito.*;version="[1.6.0,1.7.0]", + org.hamcrest.*;version="[1.1.0, 1.1.0]" \ No newline at end of file