code-small.jpg

 

Cake Team Blogs

Cake Solutions architects, implements and maintains modern and scalable software, which includes server-side, rich browser applications and mobile development. Alongside the software engineering and delivery, Cake Solutions provides mentoring and training services. Whatever scale of system you ask us to develop, we will deliver the entire solution, not just lines of code. We appreciate the importance of good testing, Continuous Integration and delivery, and DevOps. We motivate, mentor and guide entire teams through modern software engineering. This enables us to deliver not just software, but to transform the way organisations think about and execute software delivery.

 

 

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