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:
committed by
Soby Chacko
parent
bc7f794112
commit
2910d27e09
@@ -1997,6 +1997,31 @@ The bound interface is injected into the test so we can have access to both chan
|
||||
We are sending a message on the input channel and we are using the `MessageCollector` provided by Spring Cloud Stream's test support to capture the message has been sent to the output channel as a result.
|
||||
Once we have received the message, we can validate that the component functions correctly.
|
||||
|
||||
=== Disabling the test binder autoconfiguration
|
||||
|
||||
The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies.
|
||||
In some cases (e.g. integration tests) it is useful to use the actual production binders instead, and that requires disabling the test binder autoconfiguration.
|
||||
In order to do so, you can exclude the `org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration` class using one of the Spring Boot autoconfiguration exclusion mechanisms, as in the following example.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@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";
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
When autoconfiguration is disabled, the test binder is available on the classpath, and its `defaultCandidate` property is set to `false`, so that it does not interfere with the regular user configuration. It can be referenced under the name `test` e.g.:
|
||||
|
||||
----
|
||||
spring.cloud.stream.defaultBinder=test
|
||||
----
|
||||
|
||||
== Health Indicator
|
||||
|
||||
Spring Cloud Stream provides a health indicator for binders.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
test:\
|
||||
org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration
|
||||
org.springframework.cloud.stream.test.binder.TestSupportBinderConfiguration
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user