Testing Spring Integration Gateways

Testing Spring Integration Gateways

0 Comments

Last Updated on June 24, 2019 by Simanta

Spring Integration Gateways are one of my favorite features of Spring Integration. As a developer, you write an interface for the Spring Integration Gateway, and at runtime Spring Integration will provide you an implementation of the class via the Spring Context for your application to use.

What is nice about this approach, the complexities of the messaging layer is completely hidden from your application code. There is no ‘leakage’ of the messaging layer into your application layer. From the standpoint of the developer, you are simply making a method call on a class which implements the interface you wrote for your Spring Integration Gateway.

Spring Integration Gateway Example

Overview

For our example today, lets say you’re working on a large ecommerce website. You need to call a service to retrieve product data. Spring Integration is a natural choice to handle this type of request. For integration with the service on the website, you’ve decided to use a Spring Integration Gateway. This way the message based request to the backend service is completely abstracted from your existing code.

Model

For our example, we want to return a product. In a large ecommerce web site, your Product class would be much more complex. However, this simple POJO is fine for demonstrating the capabilities of Spring Integration.

package guru.springframework.si.model;

public class Product {
    private String productId;
    private String description;

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Spring Integration Gateway

Here is the code for our Spring Integration Gateway. This is the interface you will use in your application.

package guru.springframework.si.gateways;

import guru.springframework.si.model.Product;
import org.springframework.integration.annotation.Gateway;

public interface ProductGateway {

    @Gateway(requestChannel = "getProductChannel")
    Product getProduct(String productId);
}

Product Service

The Product Service could be a number of things in a real enterprise application. Might be a web service, could be a JMS or AQMP queue, a Spring Data Repository, or even a traditional DAO. For this demonstration, keep in mind this would be some type of different service you’d call to retrieve product data. I’ve created a very simple stub of a service class that just returns a Product  object.

package guru.springframework.si.testservice;

import guru.springframework.si.model.Product;
import org.springframework.stereotype.Service;

@Service
public class ProductService {
    public Product getProduct(String productId) {
        Product product = new Product();
        product.setProductId(productId);
        product.setDescription("Product from Production");

        return product;
    }
}

Spring Integration Configuration

Knowing I want to unit test my Spring Integration Gateway, I’ve decided to split up my configuration files. There’s actually a couple different ways I could have approached this in Spring, such as using Profiles. However, for what I wish to accomplish today composing the Spring configuration works just fine.

si-product-gateway.xml

In this configuration I’m defining just the gateway and the channels. Nothing else.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/integration
                  http://www.springframework.org/schema/integration/spring-integration.xsd">

    <gateway service-interface="guru.springframework.si.gateways.ProductGateway"/>

    <channel id="getProductChannel"/>

</beans:beans>

si-config.xml

For my production configuration, I import the Spring Integration configuration and the provide the rest of my Spring configuration. This is the Spring Configuration file I will use for my production environment.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/integration
                  http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <beans:import resource="classpath*:/spring/si-product-gateway.xml"/>

    <context:component-scan base-package="guru.springframework.si.testservice"/>

    <service-activator ref="productService" method="getProduct" input-channel="getProductChannel"/>
</beans:beans>

Sprint Boot Application

Spring Boot makes it very easy to bring up the Spring context and execute our Spring Integration example application.  In this class, you can see I’ve used the @SpringBootApplication  to bring up the Spring Context. I’m sourcing in the Spring Integration Configuration with the @ImportResource  annotation. When this this application runs, it will get the application context and ask for an instance of our Spring Integration Gateway. Notice in the above code, I never provided a concrete implementation of the Gateway interface. This is something that Spring Integration will do for you at run time. Once I have the ProductGateway  from the Spring context, I can ask it for a Product .

package guru.springframework.si;

import guru.springframework.si.gateways.ProductGateway;
import guru.springframework.si.model.Product;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath*:/spring/si-config.xml")
public class TestingSiGatewaysApplication {

    public static void main(String[] args) {
        ApplicationContext ctx =  SpringApplication.run(TestingSiGatewaysApplication.class, args);
        ProductGateway productGateway = (ProductGateway) ctx.getBean("productGateway");
        Product product = productGateway.getProduct("1234");

        System.out.println(product.getProductId());
        System.out.println(product.getDescription());
    }
}

When you run this class, you will see this output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.3.RELEASE)

2015-05-01 06:54:46.053  INFO 9434 --- [           main] g.s.si.TestingSiGatewaysApplication      : Starting TestingSiGatewaysApplication on Johns-MacBook-Pro.local with PID 9434 (/Users/jt/src/springframework.guru/testing-si-gateways/target/classes started by jt in /Users/jt/src/springframework.guru/testing-si-gateways)
2015-05-01 06:54:46.624  INFO 9434 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3ecd23d9: startup date [Fri May 01 06:54:46 EDT 2015]; root of context hierarchy
2015-05-01 06:54:47.379  INFO 9434 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from URL [file:/Users/jt/src/springframework.guru/testing-si-gateways/target/classes/spring/si-config.xml]
2015-05-01 06:54:47.652  INFO 9434 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from URL [file:/Users/jt/src/springframework.guru/testing-si-gateways/target/classes/spring/si-product-gateway.xml]
2015-05-01 06:54:47.752  INFO 9434 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-05-01 06:54:47.759  INFO 9434 --- [           main] o.s.i.config.IntegrationRegistrar        : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2015-05-01 06:54:47.976  INFO 9434 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2015-05-01 06:54:47.979  INFO 9434 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2015-05-01 06:54:48.133  INFO 9434 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-05-01 06:54:48.133  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class org.springframework.beans.factory.config.PropertiesFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.134  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class java.util.Properties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.136  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'messageBuilderFactory' of type [class org.springframework.integration.support.DefaultMessageBuilderFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.216  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean '(inner bean)#4ba302e0' of type [class org.springframework.integration.channel.MessagePublishingErrorHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.217  INFO 9434 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService  'taskScheduler'
2015-05-01 06:54:48.219  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'taskScheduler' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.219  INFO 9434 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationHeaderChannelRegistry' of type [class org.springframework.integration.channel.DefaultHeaderChannelRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-05-01 06:54:48.342  INFO 9434 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started productGateway
2015-05-01 06:54:48.343  INFO 9434 --- [           main] o.s.i.gateway.GatewayProxyFactoryBean    : started productGateway
2015-05-01 06:54:49.068  INFO 9434 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-05-01 06:54:49.074  INFO 9434 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2015-05-01 06:54:49.076  INFO 9434 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-05-01 06:54:49.076  INFO 9434 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator} as a subscriber to the 'getProductChannel' channel
2015-05-01 06:54:49.076  INFO 9434 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application.getProductChannel' has 1 subscriber(s).
2015-05-01 06:54:49.076  INFO 9434 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started org.springframework.integration.config.ConsumerEndpointFactoryBean#0
2015-05-01 06:54:49.076  INFO 9434 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-05-01 06:54:49.077  INFO 9434 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 1 subscriber(s).
2015-05-01 06:54:49.077  INFO 9434 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2015-05-01 06:54:49.084  INFO 9434 --- [           main] g.s.si.TestingSiGatewaysApplication      : Started TestingSiGatewaysApplication in 3.721 seconds (JVM running for 4.436)
1234
Product from Production
2015-05-01 06:54:49.106  INFO 9434 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3ecd23d9: startup date [Fri May 01 06:54:46 EDT 2015]; root of context hierarchy
2015-05-01 06:54:49.108  INFO 9434 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped productGateway
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] o.s.i.gateway.GatewayProxyFactoryBean    : stopped productGateway
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator} as a subscriber to the 'getProductChannel' channel
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application.getProductChannel' has 0 subscriber(s).
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#0
2015-05-01 06:54:49.109  INFO 9434 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-05-01 06:54:49.110  INFO 9434 --- [       Thread-1] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 0 subscriber(s).
2015-05-01 06:54:49.110  INFO 9434 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped _org.springframework.integration.errorLogger
2015-05-01 06:54:49.110  INFO 9434 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483648
2015-05-01 06:54:49.111  INFO 9434 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2015-05-01 06:54:49.112  INFO 9434 --- [       Thread-1] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'

Testing the Spring Boot Application

The Spring Boot Application, actually becomes a Spring Configuration. You can actually run this example as a JUnit Test.

package guru.springframework.si;

import guru.springframework.si.gateways.ProductGateway;
import guru.springframework.si.model.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestingSiGatewaysApplication.class)
public class TestingSiGatewaysApplicationTests {

	@Autowired
	ProductGateway productGateway;

	@Test
	public void contextLoads() {

		Product product = productGateway.getProduct("1234");

		System.out.println(product.getProductId());
		System.out.println(product.getDescription());
	}

}

Running this will produce the same output as above. While this is ‘testing’ our Spring Integration Gateway via JUnit, it is not really what we want. The configuration is still using our ‘production’ ProductService .

Unit Testing The Spring Integration Gateway

Technically what I’m showing you is not a ‘Unit’ test. Many will argue once you bring up a Spring Context, your test is now an ‘Integration’ test. I’ll let you decide what to call it.  To test my Spring Integration Gateway, I want to wire in a completely different service. In a real enterprise application, I would not want to be using the real product service for testing. I want to use some type of mock implementation.

Gateway Test Service

Here is the mock service I want to wire into my Spring Integration Gateway for testing. Very similar to the fake service I provided for our example above, in the fact that it just creates a Product instance and returns it. For purposes of illustration, you can see I’m setting the product description to:

"Product in TESTING!!"
package guru.springframework.si.testservice;

import guru.springframework.si.model.Product;
import org.springframework.stereotype.Service;

@Service
public class GatewayTestService {
    private String lastString;

    public Product getProduct(String productId){
        Product product = new Product();
        product.setProductId(productId);
        product.setDescription("Product in TESTING!!");
        return product;
    }

    public String getLastString() {
        return lastString;
    }

    public void setLastString(String lastString) {
        this.lastString = lastString;
    }
}

Spring Configuration

Above I mentioned using composition for our Spring configuration in testing. Once you become more comfortable with the Spring Framework, you will find this is a very common technique to use. You will recall, I defined just the Spring Integration Gateway interface and channels in a Spring Integration file. For my unit tests, I can provide a completely different Spring Configuration. This in effect completely changes the plumbing behind the Spring Integration Gateway.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">

       <import resource="classpath*:/spring/si-product-gateway.xml"/>

       <context:component-scan base-package="guru.springframework.si.testservice"/>

       <integration:service-activator input-channel="getProductChannel" ref="gatewayTestService" method="getProduct"/>
</beans>

JUnit Test of the Spring Integration Gateway

Here is a JUnit Test of the Spring Integration Gateway. In our test, we’re running it with the Spring JUnit Test Runner and specifying our test configuration for Spring.

package guru.springframework.si.gateway;

import guru.springframework.si.gateways.ProductGateway;
import guru.springframework.si.model.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:/spring/si-test-config.xml")
public class ProductGatewayTests {

    @Autowired
    ProductGateway productGateway;

    @Test
    public void testGetProduct(){
        Product product = productGateway.getProduct("33333");

        assertNotNull(product);
        assertEquals("33333", product.getProductId());

        System.out.println(product.getProductId());
        System.out.println(product.getDescription());
    }
}

When you run the above test, it will pass the assertions. Also in the console you will see the following output:

07:23:40.988 [main] DEBUG o.s.i.h.ServiceActivatingHandler - ServiceActivator for [org.springframework.integration.handler.MethodInvokingMessageProcessor@6ccdb29f] received message: GenericMessage [payload=33333, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3adcc812, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3adcc812, id=fd8d43a6-a45f-ef16-45a1-a1a45473323b, timestamp=1430479420988}]
07:23:40.993 [main] DEBUG o.s.i.channel.DirectChannel - postSend (sent=true) on channel 'getProductChannel', message: GenericMessage [payload=33333, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3adcc812, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3adcc812, id=fd8d43a6-a45f-ef16-45a1-a1a45473323b, timestamp=1430479420988}]
07:23:40.994 [main] DEBUG o.s.i.g.GatewayProxyFactoryBean - Unable to attempt conversion of Message payload types. Component 'productGateway' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
33333
Product in TESTING!!
07:23:40.997 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@a7e666 testClass = ProductGatewayTests, testInstance = guru.springframework.si.gateway.ProductGatewayTests@68bbe345, testMethod = testGetProduct@ProductGatewayTests, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@30b8a058 testClass = ProductGatewayTests, locations = '{classpath*:/spring/si-test-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
07:23:41.001 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@a7e666 testClass = ProductGatewayTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@30b8a058 testClass = ProductGatewayTests, locations = '{classpath*:/spring/si-test-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
07:23:41.004 [Thread-1] INFO  o.s.c.s.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@3712b94: startup date [Fri May 01 07:23:40 EDT 2015]; root of context hierarchy
0

Notice how the product description is ‘Product In Testing’, proving that our test service was used, and not our ‘production’ service.

Spock Test of the Spring Integration Gateway

For fun, lets run the same test using Spock. Spock has become my favorite testing framework to use. If you’re not using Spock, you should be!

package guru.springframework.si.gateway

import guru.springframework.si.gateways.ProductGateway
import guru.springframework.si.model.Product
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification

@ContextConfiguration(locations = "classpath*:/spring/si-test-config.xml")
class ProductGatewaySpecTests extends Specification{

    @Autowired
    ProductGateway productGateway

    def "Test get product gateway"() {
        given:
        def productId = '122222'

        when:
        Product product = productGateway.getProduct('122222')

        println product?.productId
        println product?.description

        then:
        product
        product.productId == productId
    }
}

When you run the Spock Specification, you will see the following output:

07:29:33.359 [main] DEBUG o.s.i.channel.DirectChannel - postSend (sent=true) on channel 'getProductChannel', message: GenericMessage [payload=122222, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@222eb8aa, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@222eb8aa, id=30f5e380-47c9-7671-0bcc-6effb1666e78, timestamp=1430479773356}]
07:29:33.359 [main] DEBUG o.s.i.g.GatewayProxyFactoryBean - Unable to attempt conversion of Message payload types. Component 'productGateway' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
122222
Product in TESTING!!
07:29:33.376 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@4f83df68 testClass = ProductGatewaySpecTests, testInstance = guru.springframework.si.gateway.ProductGatewaySpecTests@6cf0e0ba, testMethod = $spock_feature_0_0@ProductGatewaySpecTests, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@7d8995e testClass = ProductGatewaySpecTests, locations = '{classpath*:/spring/si-test-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
07:29:33.378 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@4f83df68 testClass = ProductGatewaySpecTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@7d8995e testClass = ProductGatewaySpecTests, locations = '{classpath*:/spring/si-test-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].

Again, you can see all the assertions passed, and the output is ‘Product in Testing’.

Conclusion

Spring Integration Gateways are a great feature of Spring Integration. In this blog post, I’ve shown you how you can compose your Spring configuration files to change the behavior of Spring Integration for testing. I hope you can see how easy it is to wire up different configurations in Spring and Spring Integration.

Get The Code

I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to Spring tutorial. You can sign up for this tutorial in the section below.

Source Code

The source code for this post is available on github. You can download it here.

About jt

    You May Also Like

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.