IgorShare Weblog

Practical Engineering

Archive for the ‘Java’ Category

Mocking, embedded-Jetty and expectations for outgoing HTTP requests in Java

Posted by igormoochnick on 09/05/2008

If your classes in Java are executing outgoing HTTP calls it’s not easy to unit-test them. In many cases it requires to set-up separate web servers and deploy a test-verification code. I’m going to give you a way to do it in-line, just as you do it with any other unit-test.

In order to do this we’ll use embedded-Jetty. We’ll host Jetty inside the unit-testing framework.

For our example I’m going to use a TestNG unit-testing framework, but, as you can guess, you’re welcome to use any other you see fit.

1. First of all we need to initialize Jetty. We’re going to do it in @BeforeClass method:

private Server server;
private String returnUrl;

@BeforeClass
@Parameters({ "test-jetty-port" })
public void setUpJetty(@Optional("8123") int testPort) throws Exception
{
	server = new Server(testPort);

	Handler handler = new AbstractHandler()
	{
	    public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
	        throws IOException, ServletException
	    {
	        handleHttpRequest(target, request, response);
	    }
	};

	returnUrl = "http://localhost:" + Integer.toString(testPort) + "/test";

	server.setHandler(handler);

	server.start();
}

2. In order to consume all the incoming HTTP traffic we’re going to define a handler (we’re going to discuss other opportunities in the following posts). Note that the incoming HTTP traffic is stored inside the HttpTester parser class:

private HttpTester requestTest = new HttpTester();

private String getRequestString(HttpServletRequest request) throws Exception
{
	ServletInputStream reqz = request.getInputStream();
	int contentLen = request.getContentLength();
	if (contentLen == -1)
		return request.toString();

	byte[] buff = new byte[contentLen];
	int realLen = reqz.read(buff);

	Assert.assertEquals(realLen, contentLen, "Content length from parameter should be equal to the real content length");

	return request.toString() + new String(buff);
}

public void handleHttpRequest(String target, HttpServletRequest request, HttpServletResponse response)
{
	try
	{
		requestTest.parse( getRequestString(request) );
	}
	catch(Exception e)
	{
		Assert.fail("Failed to parse the incoming request.", e);
	}

    response.setContentType("text/html");
    response.setStatus(HttpServletResponse.SC_OK);
    ((Request)request).setHandled(true);
}

3. And this is how you can define your test fixture:

@Test
public void jobReport_returns_POST_reply() throws Exception
{
    String xml = "<xml>some-data-here</xml>";

    object-to-test.send_post(returnUrl, xml);

    Assert.assertEquals(requestTest.getMethod(), "POST");
    Assert.assertEquals(requestTest.getURI(), "/test");
    Assert.assertEquals(requestTest.getContent(), xml);
}

4. After all the tests are done, don’t forget to shutdown the Jetty server:

@AfterClass
public void tearDownJetty() throws Exception
{
	server.stop();
}

Posted in Java, Jetty, Mocking, TestNG, Unit Testing | 1 Comment »

Terracotta project – the best user experience ever

Posted by igormoochnick on 06/20/2008

Wow!  This is the best user experience I’ve ever had.

The documentation is clean, crisp and to the point. The installation went smooth and, after the installation, I was asked if I’d like to run some demo application. Without leaving the installation program (post-install) I was able to run pre-built samples that demonstrated the beauty of the product and made me feel safe and sound that the installed product is operational.

Good job, guys!  I wish other product would’ve followed your track with the user experience.

Useful Links

Terracotta project home – http://www.terracotta.org/

Terracotta tutorials – http://www.terracotta.org/confluence/display/explore/Home

Posted in Java, Thoughts, Tutorials | Leave a Comment »