Evolution in Data Integration From EII to Big Data
Approaches to integrating data are changing with emergence of cloud computing.
The content has been bookmarked!
There was an error bookmarking this content! Please retry.
Posted by Kostis Kapelonis on Nov 25, 2011
EclipseSource has released the first stable version for an open source JUnit extension that automates testing of REST/HTTP services. Restfuse is a set of JUnit annotations that, along with the respective HttpJUnitRunner, offer assertions against the response of an HTTP call. Both synchronous and asynchronous remote calls are supported.
Restfuse is already in Maven Central so using it requires no special repository:
<dependency>
<groupId>com.restfuse</groupId>
<artifactId>com.eclipsesource.restfuse</artifactId>
<version>1.0.0</version>
</dependency>
Using the library for synchronous calls is straightforward:
@RunWith( HttpJUnitRunner.class )
public class RestFuseTest {
@Rule
public Destination destination = new Destination( "http://example.com" );
@Context
private Response response; // will be injected after every request
@HttpTest( method = Method.GET, path = "/reloadLocalConfiguration" )
public void checkRestfuseOnlineStatus() {
assertOk( response );
String answerBody = response.getBody(String.class);
assertEquals("Expected correct response","done",answerBody);
}
}
The test above calls an HTTP endpoint synchronously and then checks for a text-based response (text/plain) with the "done" string. Notice that the first assertOk is a Restfuse assert that checks for the HTTP 200 OK status call while the second assertEquals is the usual string equality assert offered by JUnit. While this endpoint is assumed to return plain text, one could easily parse JSON/XML or something else and perform asserts in a structured manner.
Restfuse also supports asynchronous calls. The canonical example is a long running operation (e.g. progress on a file upload). The client continuously polls the server endpoint in order to gather constant feedback on the actual status. Let's assume a server endpoint that returns a number between 0 and 100 that denotes progress on some operation:
@RunWith( HttpJUnitRunner.class )
public class PollTest1 {
@Rule
public Destination destination = new Destination( "http://example.com" );
@Context
private Response response;
@Context
private PollState pollState;
@HttpTest( method = Method.GET, path = "/progressStatus" )
@Poll( times = 5, interval = 500 )
public void testAsynchronousService() {
if(pollState.getTimes() == 5)
{
String answerBody = response.getBody(String.class);
assertEquals("Expected last response","100",answerBody);
}
}
}
The test above calls the same endpoint 5 times (with a specified interval) and only on the last call checks the actual HTTP response.
Another interesting feature of the PollState Interface is that it keeps track of all the previous responses at each point in time. This allows for asserts on the history of the calls:
@RunWith( HttpJUnitRunner.class )
public class PollTest2 {
@Rule
public Destination destination = new Destination( "http://example.com" );
@Context
private Response response;
@Context
private PollState pollState;
@HttpTest( method = Method.GET, path = "/progressStatus" )
@Poll( times = 5, interval = 500 )
public void testAsynchronousService() {
int currentRun = pollState.getTimes();
if(currentRun > 1)
{
String previousProgress = pollState.getResponse(currentRun - 1).getBody(String.class);
String presentProgress = response.getBody(String.class);
assertTrue("Expected some progress",Integer.parseInt(presentProgress) > Integer.parseInt(presentProgress)); //Just for illustration purposes
}
}
}
}
The test above checks that each response is a higher number than the previous one.
One of the most surprising dependencies of Restfuse is the Jetty HTTP server. The reason for this is that Restfuse also supports asynchronous services that follow the Web Hooks guidelines. Instead of polling multiple times the server, a client endpoint performs a call only once and then waits for a response initiated by the server in a completely different connection. Here is the Restfuse example:
@RunWith( HttpJUnitRunner.class )
public class RestfuseCalbackTest {
@Rule
public Destination destination = new Destination( "http://example.com" );
@Context
private Response response;
private class TestCallbackResource extends DefaultCallbackResource {
@Override
public Response post( Request request ) {
assertTrue("Expected a quote response", request.getBody(String.class).startsWith("quote:") );
return super.post( request );
}
}
@HttpTest( method = Method.GET, path = "/requestQuote" )
@Callback( port = 9090, path = "/asynchron", resource = TestCallbackResource.class, timeout = 10000 )
public void testMethod() {
assertAccepted( response );
}
}
The example above will connect to requestQuote once and then listen to port 9090 of the client. Within 10 seconds it will expect a connection that is text-based and starts with "quote:".
For more extensive information, visit the Wiki, and Javadocs. The source code is hosted on GitHub.
Monitor your Production Java App - includes JMX! Low Overhead - Free download
Using Drools? See what you're missing! Get the Power of Drools with the Assurance of Red Hat
In today’s hyper-competitive world, later may be too late to adopt Agile development and this Roadmap for Success will help you get started. Download "Agile Development: A Manager's Roadmap for Success" now!
Approaches to integrating data are changing with emergence of cloud computing.
Michele Ide-Smith presents the lessons learned in the process of introducing UX principles and techniques into a large organization through a series of small steps.
Dave Farley and Martin Thompson discuss solutions for doing low-latency high throughput transactions based on the Disruptor concurrency pattern.
Rajneesh Namta shares his thoughts, experiences, and some of the critical lessons learned while implementing software test automation on a recent Agile project.
Dale Schumacher presents several patterns of actor interaction that can be used in collaborative programs written in any language.
Rúnar Bjarnason discusses Scalaz, a Scala library of pure data structures, type classes, highly generalized functions, and concurrency abstractions to perform functional programming in Scala.
One of the main challenges when designing software architecture is considering quality attributes. Not only their design turns out to be difficult, but also the specification of these attributes.
Michael Feathers analyzes real code bases concluding that code is not nearly as beautiful as designers aspire to, discussing the everyday decisions that alter the code bit by bit.
No comments
Watch Thread Reply