Testing Spring Integration Gateways

Testing Spring Integration Gateways

0 Comments

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.

Spring Integration Gateway

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

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.

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.

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.

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 .

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

Testing the Spring Boot Application

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

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: 

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. 

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.

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

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!

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

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.
0

About jt

    You May Also Like

    Leave a Reply