Friday, February 22, 2013

Test fixtures - using XML Spring bean definition vs Java Configuration

Spring's Java based container configuration is a neat way of specifying Spring bean configurations and in my own projects I have systematically replaced XML configuration with Java Bean configuration where feasible.

However, there are still a few places where an XML bean configuration is a better fit than the Java Configuration, here I am focusing on one such use case.

Consider a test case which requires a fixture with a lot of test instances of domain classes, assume a simple domain of a Member(a person) with an address. This would be expressed the following way using a Spring XML configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:c="http://www.springframework.org/schema/c"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean name="member1" class="el.Member" c:first="First1" c:last="Last1" c:address-ref="address1"/>
 <bean name="member2" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address2"/>
 <bean name="member3" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address3"/>
 <bean name="member4" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address4"/>
 <bean name="member5" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address5"/>
 
 <bean name="address1" class="el.Address" c:city="City1" c:state="State1"/>
 <bean name="address2" class="el.Address" p:city="City2" p:state="State2"/>
 <bean name="address3" class="el.Address" p:city="City3" p:state="State3"/>
 <bean name="address4" class="el.Address" p:city="City4" p:state="State4"/>
 <bean name="address5" class="el.Address" p:city="City5" p:state="State5"/>
</beans>




The good thing about this configuration is that it is very easy to see the list of entities with Spring's c (constructor) and p(property) custom xml namespaces allowing a very concise expression.

On the other hand if the same fixture had been created through Java Configuration it would be a little more verbose, especially for cases where setters are used(like in member5 below):

@Configuration
public class FixturesJavaConfig {

 @Bean public Member member1(){return new Member("first1", "last1", address1());}
 @Bean public Member member2(){return new Member("first2", "last2", address1());}
 @Bean public Member member3(){return new Member("first3", "last3", address1());}
 @Bean public Member member4(){return new Member("first4", "last4", address1());}
 
 @Bean public Member member5(){
  Member member = new Member();
  member.setFirst("first5");
  member.setLast("last5");
  member.setAddress(address5());
  return member;
 }
 
 @Bean public Address address1(){return new Address("city1", "state1");}
 @Bean public Address address2(){return new Address("city2", "state2");}
 @Bean public Address address3(){return new Address("city3", "state3");}
 @Bean public Address address4(){return new Address("city4", "state4");}
 @Bean public Address address5(){return new Address("city5", "state5");}
}

A matter of choice at the end of the day I suppose, but this has become a pattern that I have been using now - use Java Configuration where feasible, but use XML configuration for cases where a bunch of test fixtures need to be created.

No comments:

Post a Comment