Sunday, April 22, 2012

JUnit Testing - Springs


Testing MVC (mode view controller) architecture based Spring application is very easy thanks to the mock testing framework provided by Spring. Without starting the server, controller code and service layer code can be tested. This tutorial is intended for Spring2.5(x) or later.

Please download source code from here. Download the two classes into your project (place them under a test folder to distinguish them from the source code). MockWebApplicationContextTestCase.java is the main class where all the magic happens. Inherit this class and you will be ready. SanityTest.java is provided as an example test class that makes use of MockWebApplicationContextTestCase.java to test a Controller class.

Requirements:
  1. Spring jars required to implement MVC application.
  2. Spring-test.jar - contains all the main classes required for Mock testing.
  3. Junit4 jar - Please note that when integrating Spring 2.5.x with Junit and use SpringJUnit4ClassRunner.class  as the runner class for Junit, it has been found that Junit 4.4 was the compatible version. For Spring 3.x, Junit 4.5 or later can be used.

Explanation:
  1. First, we need access to ApplicationContext object of Spring to get hold all the objects defined in Spring definition files. As we are trying to test Spring MVC, it would be better to have access to GenericWebApplicationContext instead of GenericApplicationContext to have finer control over Web based Java objects like ServletRequest,  ServletResponse, ServletContext objects. As a side note, Spring's TilesConfigurer class used for implementing tiles is only compliant with GenericWebApplicationContext (See E1 for details). In this Mock framework, we will be using MockServletRequest, MockServletResponse, MockServletContext classes provided by Spring.
  2. In the MockWebApplicationContextTestCase, you will see that it has been configured in such a way that any transaction is automatically rolled back thus preventing the corruption of data in the back end database.
  3. You will also be able to override a particular bean definition by having your own test spring bean configuration file and placing it on the class path. See @ContextConfiguration in that class. 

Reference:

Errors/Warnings:
  • (E1) java.lang.IllegalStateException: WebApplicationObjectSupport instance [org.springframework.web.servlet.view.tiles.TilesConfigurer@] does not run in a WebApplicationContext but in: org.springframework.context.support.GenericApplicationContext@ :

Thursday, April 19, 2012

How String objects get stored in Memory?

String Object is immutable. Meaning: The object cannot be changed after it is created. Consider the following example.

String a = "hello" ; // lets assume this gets stored in address space &XYZ

When we append "world" to "hello" like below
a = a + "world";
The new String "hello world" will not replace the value "hello" in &XYZ but stored in a new address space &ZYX. Therefore, Variable "a" now points to the address &ZYX. Note that &XYZ does not get garbage collected (typically, objects get garbage collected when there is no reference to them anymore).

As a result, there are now two Strings in the Memory.
"hello" and "hello world"

So, we have to be careful when appending the string objects as the memory foot print rapidly increases with every string modification. Further, String objects are not garbage collected after their usage but are kept in the memory pool for later re-use.

There is a separate string memory pool different from standard pool where all String Objects are stored. If two strings with the same value are created, the second string and the first string point to the same address space thus reusing the memory space.

Ex:
String a = "hello";
String b = "hello";
In the above case, both "a" and "b" point to the same address &XYZ.
a = a + "world";
Now, a will point to address &ZYX while b will continue to point to &XYZ address.

Alternative to String: StringBuffer and StringBuilder are Mutable Objects. Consider using these if there is a need for too many string modifications in your code base.