Improve support for disabling TestSupportBinderAutoConfiguration

Fixes #573

- Split TestSupportBinderAutoConfiguration into separate configs
  for the binder, binderfactory and message collector.
  This enables to address the testBinder as a regular binder when
  autoconfiguration is disabled, and to ensure that the message
  collector is available when the autoconfiguration is disabled.
- reorganize tests to use the default autoconfiguration options
- add documentation for disabling test binder autoconfiguration
This commit is contained in:
Marius Bogoevici
2017-07-13 14:38:27 -04:00
committed by Soby Chacko
parent bc7f794112
commit 2910d27e09
9 changed files with 203 additions and 20 deletions

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2017 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.cloud.stream.test.binder;
import org.springframework.cloud.stream.binder.BinderFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.MessageChannel;
/**
* Automatically registers the {@link MessageCollector} associated with the test binder as
* a bean.
*
* @author Marius Bogoevici
*/
@Configuration
public class MessageCollectorAutoConfiguration {
@Bean
public MessageCollector messageCollector(BinderFactory binderFactory) {
return ((TestSupportBinder) binderFactory.getBinder("test", MessageChannel.class)).messageCollector();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2017 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.
@@ -23,6 +23,7 @@ import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.cloud.stream.binder.ProducerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.messaging.MessageChannel;
@@ -34,29 +35,24 @@ import org.springframework.messaging.MessageChannel;
* configuration, so adding this on the classpath in test scope is sufficient to have
* support kick in and replace all binders with the test binder.
*
* The test binder instance is supplied by the {@link TestSupportBinderConfiguration}.
*
* @author Eric Bottard
* @author Marius Bogoevici
*/
@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Import(TestSupportBinderConfiguration.class)
public class TestSupportBinderAutoConfiguration {
private Binder<MessageChannel, ?, ?> messageChannelBinder = new TestSupportBinder();
@Bean
public BinderFactory binderFactory() {
public BinderFactory binderFactory(final Binder<MessageChannel, ?, ?> binder) {
return new BinderFactory() {
@Override
public <T> Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties> getBinder(
String configurationName, Class<? extends T> bindableType) {
return (Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties>) messageChannelBinder;
return (Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties>) binder;
}
};
}
@Bean
public MessageCollector messageCollector(BinderFactory binderFactory) {
return ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)).messageCollector();
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2017 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.cloud.stream.test.binder;
import org.springframework.cloud.stream.binder.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.MessageChannel;
/**
* Binder {@link org.springframework.context.annotation.Configuration} for the
* {@link @TestBinder}.
*
* Either imported by the {@link TestSupportBinderAutoConfiguration} for the test binder
* default usage scenario (superseding all binders on the classpath), or used as a binder
* configuration on the classpath when test binder autoconfiguration is disabled.
*
* @author Marius Bogoevici
*/
@Configuration
public class TestSupportBinderConfiguration {
private Binder<MessageChannel, ?, ?> messageChannelBinder = new TestSupportBinder();
@Bean
public Binder<MessageChannel, ?, ?> binder() {
return messageChannelBinder;
}
}

View File

@@ -1,2 +1,2 @@
test:\
org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration
org.springframework.cloud.stream.test.binder.TestSupportBinderConfiguration

View File

@@ -1,4 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration:\
org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration,\
org.springframework.cloud.stream.test.binder.MessageCollectorAutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.stream.test.binder.TestBinderEnvironmentPostProcessor

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.stream.test.aggregate;
package org.springframework.cloud.stream.test.aggregate.bean;
import java.util.concurrent.TimeUnit;

View File

@@ -14,19 +14,19 @@
* limitations under the License.
*/
package org.springframework.cloud.stream.test.aggregate;
package org.springframework.cloud.stream.test.aggregate.main;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.aggregate.AggregateApplication;
import org.springframework.cloud.stream.aggregate.AggregateApplicationBuilder;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.cloud.stream.test.binder.MessageCollector;
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Transformer;
@@ -43,9 +43,10 @@ public class AggregateWithMainTest {
@Test
public void testAggregateApplication() throws InterruptedException {
// emulate a main method
ConfigurableApplicationContext context = new AggregateApplicationBuilder(
TestSupportBinderAutoConfiguration.class).from(UppercaseProcessor.class)
.namespace("upper").to(SuffixProcessor.class).namespace("suffix").run();
ConfigurableApplicationContext context = new AggregateApplicationBuilder(MainConfiguration.class)
.from(UppercaseProcessor.class).namespace("upper")
.to(SuffixProcessor.class).namespace("suffix")
.run();
AggregateApplication aggregateAccessor = context.getBean(AggregateApplication.class);
MessageCollector messageCollector = context.getBean(MessageCollector.class);
@@ -58,6 +59,10 @@ public class AggregateWithMainTest {
context.close();
}
@SpringBootApplication
public static class MainConfiguration {
}
@Configuration
@EnableBinding(Processor.class)
public static class UppercaseProcessor {

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2017 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.cloud.stream.test.disable;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.cloud.stream.test.binder.MessageCollector;
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Marius Bogoevici
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = AutoconfigurationDisabledTest.MyProcessor.class, properties = {
"server.port=-1",
"spring.cloud.stream.defaultBinder=test"
})
@DirtiesContext
public class AutoconfigurationDisabledTest {
@Autowired
public MessageCollector messageCollector;
@Autowired
public Processor processor;
@Test
public void testAutoconfigurationDisabled() throws Exception {
processor.input().send(MessageBuilder.withPayload("Hello").build());
// Since the interaction is synchronous, the result should be immediate
Message<?> response = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(response).isNotNull();
assertThat(response.getPayload()).isEqualTo("Hello world");
}
@SpringBootApplication(exclude = TestSupportBinderAutoConfiguration.class)
@EnableBinding(Processor.class)
public static class MyProcessor {
@Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public String transform(String in) {
return in + " world";
}
}
}