code-small.jpg

Cake Team Blogs

More BeanTables

Posted by Jan Machacek

Find me on:

06/09/11 13:08

The initial (read barely working) version of BeanTables is at github.com/janm399/specs2-spring; I'll add it to our Jenkins after lunch and it will be available at our Maven repository later on in the afternoon.

What's included?

The BeanTables trait works just like DataTables, but it works with your beans rather than tuples. In addition to the usual |> method, I have added |< methods that return the data as a List. All examples refer to the same standard Java beans:

@Entity
public class Rider {
	@Id
	@GeneratedValue
	private Long id;
	@Version
	private int version;
	@NotNull
	private String name;
	private String teamName;
	private int age;
	@OneToMany
	private Set&lt;Entry&gt; entries = new HashSet&lt;Entry&gt;();

	public void addEntry(Entry entry) {
		entry.setRider(this);
		this.entries.add(entry);
	}

	…

}

@Entity
public class Entry {
	@Id
	@GeneratedValue
	private Long id;
	@Version
	private int version;
	@ManyToOne
	private Rider rider;
	private Date time;
	private int number;

	…
}

The Specs2 specification with BeanTables that constructs the Rider beans and performs some test on them is very similar to the DataTables approach:

class BeanTableSpec extends Specification with BeanTables {
  "Simple test" in {
    "age" | "name" | "teamName" |
     32   ! "Jan"  ! "Wheelers" |
     30   ! "Ani"  ! "Team GB"  |> { r: Rider => r.getAge must be_&gt;(29) }
  }
}

If you ever need to construct Lists of objects to be used later (in other words, if you cannot write the specifications in-line), you can use the new |< method overloads. (The reason for the name |< is that it gives the value back to the left, presumably to some value.)

class BeanTableSpec extends Specification with BeanTables {
  "Simple list" in {
    val riders =
     "age" | "name" | "teamName" |
      32   ! "Jan"  ! "Wheelers" |
      30   ! "Ani"  ! "Team GB"  |&lt;(classOf[Rider])

    // riders is List[Rider] with two elements
    riders.size must be_==(2)
  }
}

Another overload of the |< method takes a function that applies some processing to the bean type T before offering it to the returned list:

class BeanTableSpec extends Specification with BeanTables {
  "Complex bean setup" in {
    val riders =
     "age" | "name" | "teamName" |
      32   ! "Jan"  ! "Wheelers" |
      30   ! "Ani"  ! "Team GB"  |< { r: Rider =>
      "number" | "time"     |
       1       ! new Date() |
       2       ! new Date() |< { e: Entry => r.addEntry(e) }
    }

    // riders is List[Rider] and each element's entries have been added
    riders.size must be_==(2)
  }
}

Use for test data setup

Very frequently, we need to insert some objects using Hibernate. Having the BeanTables trait, it was a logical step to add the HibernateDataAccess trait that, amongst other methods, includes overloads of the method insert, which return function that can be supplied to the |> method used in the BeanTables innards. Say what?
All I meant to say is that you can now bulk-insert all such objects in a single call:

@IntegrationTest
class SomeComponentSpec extends Specification
  with HibernateDataAccess with BeanTables {

  "Insert all" in {
    "age" | "name" | "teamName" |
     32   ! "Jan"  ! "Wheelers" |
     30   ! "Ani"  ! "Team GB"  |&gt; insert[Rider]

    // do stuff with the inserted objects
    this.hibernateTemplate.loadAll(classOf[Rider]) must have size(2)
  }
}

If you want to apply some processing before the objects are inserted, you can use the second overload of the insert method:

@IntegrationTest
class SomeComponentSpec extends Specification
  with HibernateDataAccess with BeanTables {

  "Insert all with entries set" in {
    "age" | "name" | "teamName" |
     32   ! "Jan"  ! "Wheelers" |
     30   ! "Ani"  ! "Team GB"  |&gt; insert[Rider] { r: Rider => r.addEntry(…) }

    // do stuff with the inserted objects
    this.hibernateTemplate.loadAll(classOf[Rider]) must have size(2)
  }
}

Topics: Specs2

Posts by Topic

see all

Subscribe to Email Updates