Friday, March 1, 2013

Test Fixtures - Using Spring scala

Continuing on my previous blog entry about creating test fixtures using Spring XML bean configuration file and the newer Spring @Configuration style, this time around I wanted to see how the same configuration turns out using the new Spring Scala project.

So this is what I had as a test fixture defined using xml bean configuration earlier:

<?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="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"/>

 <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"/>
 
</beans>

and using Java @Configuration:

@Configuration
public class FixturesJavaConfig {
 @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");}

 @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;
 }
}


Now, using Spring scala the bean configuration is the following:

import org.springframework.scala.context.function.FunctionalConfiguration

class MemberConfiguration extends FunctionalConfiguration {
  val address1 = bean() { new Address("city1", "state1") }
  val address2 = bean() { new Address("city2", "state2") }
  val address3 = bean() { new Address("city3", "state3") }
  val address4 = bean() { new Address("city4", "state4") }
  val address5 = bean() { new Address("city5", "state5") }

  bean("member1") { new Member("first1", "last1", address1()) }
  bean("member2") { new Member("first2", "last2", address2()) }
  bean("member3") { new Member("first3", "last3", address3()) }
  bean("member4") { new Member("first4", "last4", address4()) }
  bean("member5") {
    val member = new Member()
    member.setFirst("first5");
    member.setLast("last5");
    member.setAddress(address5());
    member
  }
}

The fixture configuration does look very clean and concise and I would definitely be looking out for the spring-scala project as it matures a little more - a few things which will need to be implemented are a way for bootstrapping this configuration with Spring based tests(through @ContextConfiguration), way to import this configuration into normal xml based bean configurations and into java based @Configurations.
For Scala only projects the Spring Scala project does look very promising.

Finally, this is a test for the "FunctionalConfiguration" above:

import org.scalatest.FunSuite
import org.springframework.scala.context.function.FunctionalConfigApplicationContext
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
@RunWith(classOf[JUnitRunner])
class MemberConfigTest extends FunSuite {
  test("there should be 5 members in the configuration") {
    val applicationContext = new FunctionalConfigApplicationContext(classOf[MemberConfiguration])
    val members = applicationContext.getBeansOfType(classOf[Member])
    assert(members.size() === 5)
  }
}