Main Menu



You are here: Home
Using Mocks to Speed Network / Web Development with Java PDF Print E-mail
Written by Josh B   
Friday, 26 February 2010 12:43

Tags: java | junit | testing

Mocking is a great way to save time when developing. For example, say you are developing a service which interacts with a Remote Website via some kind of http interface. In order to test this fully with Junit you have to test each different error before you were confident that your code was completely robust. This might take forever, especially with rare error conditions. We also may put undue strain on the website with all this testing and annoy the Webmaster. This is where Mocking can come in handy.

The following assumes we retrieve data from our website in the class WebClient that has a method like:

private String getData (String username, String password) {
HttpClientIf httpClientIf = new HttpClient ();
URL url = new URL ("http://www.example.com/myhttpservice.php");
String requestBody = "username=" + username + "&password=" + password;
httpClientIf.setRequestBody(requestBody);
int result = httpClientIf.executePost(url);
logger.info("response : " + result);
if (result != HttpURLConnection.HTTP_OK) {
throw new Exception ("Oh Noes...!");
}
String response = httpClientIf.getResponse();
logger.info("response : " + response);
return response
}

In the above we are trying to post data to a url with expectation we will get something back. We can then parse, or scrape, this response for our purposes.

In order to test this in our Junit test, we could have the following test:

public void testGetTokenWorks() throws Exception {

String expectedResponse = "<html><body>Something...</body></html>";

String username = "username";
String password = "password";

WebClient client = new WebClient ();

String response = client.getData (username, password);
Assert.assertTrue (response.equals (expectedResponse));
}

However this only tests for a successful retrieval. How can we can test that the Exception gets thrown...? Well, we could use non-existent user-names and passwords. But in some situations that might get us into trouble...

First, add this to your pom.xml file so that Maven picks up the dependency:

<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<version>1.1</version>
</dependency>

And then we can write a Junit test like:

// make sure you have the correct jar in your classpath
// or listed as a dependency in Maven
import org.easymock.MockControl;

public class WebClientMockTest extends TestCase {

private MockControl control;
private HttpClientIf mock;

public void setUp() throws Exception {
super.setUp();

control = MockControl.createControl(HttpClientIf.class);
mock = (HttpClientIf) control.getMock();

}

public void testWebClientMock() throws Exception {

URL url = null;

// start setting up the responses the Mock will give
mock.setRequestBody("");
control.setDefaultVoidCallable();

mock.executePost(url);
control.setDefaultReturnValue(403);

mock.getResponse();
control.setDefaultReturnValue("Error Response");

String username = "username";
String password = "password";

WebClient client = new WebClient ();

// we would need to add this method to WebClient
client.setHttpClient(mock);

mock.replay();

// when this is called a 403 error would be returned by
// the mocked HttpClientIf
String response = client.getData (username, password);

// double check that the request fired...
control.verify();

// reset the mock
control.reset();
}
}

The above code will now reliably generate 403 return codes and one can now develop code that will deal with this situation. Once you have dealt with this error-code you can then move on to deal with other error conditions. Using Mocks is an easy way to test various conditions, and is very useful when doing any web or networking development with Java...!

Last Updated on Friday, 26 February 2010 12:53
 

Add comment


Security code
Refresh

Joomla! Template by Red Evolution - Joomla Web Design