<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Adrian Hummel</title>
	<atom:link href="http://adrianhummel.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://adrianhummel.wordpress.com</link>
	<description>Java. Software. Design. Applied.</description>
	<lastBuildDate>Tue, 12 Jul 2011 14:25:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='adrianhummel.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Adrian Hummel</title>
		<link>http://adrianhummel.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://adrianhummel.wordpress.com/osd.xml" title="Adrian Hummel" />
	<atom:link rel='hub' href='http://adrianhummel.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Specification using JPA 2.0 Criteria API &#8211; Source Code</title>
		<link>http://adrianhummel.wordpress.com/2011/07/11/specification-using-jpa-2-0-criteria-api-source-code/</link>
		<comments>http://adrianhummel.wordpress.com/2011/07/11/specification-using-jpa-2-0-criteria-api-source-code/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 20:39:40 +0000</pubDate>
		<dc:creator>adrianhummel</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Trivadis]]></category>

		<guid isPermaLink="false">http://adrianhummel.wordpress.com/?p=138</guid>
		<description><![CDATA[In my previous article I showed how to create composed specifications using the JPA 2.0 Criteria API. This article shows the source code of the Specification interface and the core components (including boolean operators). We first start with the Specification interface: Based on the ideas published by Eric Evans (author of the book &#8220;Domain Driven [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=138&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In my <a title="Composed Specification using JPA 2.0" href="https://adrianhummel.wordpress.com/2010/07/02/composed-specifications-using-jpa-2-0/">previous article</a> I showed how to create composed specifications using the JPA 2.0 Criteria API. This article shows the source code of the Specification interface and the core components (including boolean operators).</p>
<p>We first start with the Specification interface:</p>
<pre class="brush: java;">
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
* &lt;code&gt;Specification&lt;/code&gt; is used to test an object to see if it satisfies
* a certain criteria.
*
* @author had
* @author http://dddsample.sourceforge.net/
*
* @param  The type of the object to test.
*/
public interface Specification {
  /**
  * Tests the specified &lt;code&gt;candidate&lt;/code&gt; if it satisfies the criteria
  * of this specification.
  * @param candidate The object to test.
  * @return &lt;code&gt;true&lt;/code&gt; if &lt;code&gt;testObject&lt;/code&gt; satisfies the
  * criteria of this specification, &lt;code&gt;false&lt;/code&gt; otherwise.
  */
  boolean isSatisfiedBy(T candidate);

  /**
  * Transforms this specification into a predicate. (optional)
  * @param cb The criteria builder to use, must not be null.
  * @param query The query object to use, must not be null.
  * @param root The starting point, must not be null.
  * @return The created predicate which checks the rules.
  * @throws UnsupportedOperationException If this specification does not
  *  support predicate transformation.
  */
  Predicate toPredicate(CriteriaBuilder cb, CriteriaQuery query, Root root) throws UnsupportedOperationException;

  Specification and(Specification other);

  Specification or(Specification other);

  Specification not();
}
</pre>
<p>Based on the ideas published by Eric Evans (author of the book &#8220;Domain Driven Design&#8221;), this interface contains the following methods:</p>
<ul>
<li>isSatisfiedBy &#8211; to check an in-memory object if it satisifies the specification</li>
<li>and, or, not &#8211; for boolean operations on the specification</li>
</ul>
<p>The interface above has an additional method called toPredicate. This method transforms the (business-driven) intention of the specification into a Predicate which is used to fetch all persisted objects satisfying the specification &#8211; one important aspect of the Specification concept. The Predicate interface is defined by the JPA 2.0 Criteria API and can be used to build dynamic queries using predicates (as shown in the <a title="Composed Specification using JPA 2.0" href="https://adrianhummel.wordpress.com/2010/07/02/composed-specifications-using-jpa-2-0/">previous article</a>).</p>
<p>An abstract specification implements the Specification interface as follows:</p>
<pre class="brush: java;">
public abstract class AbstractSpecification&lt;T&gt; implements Specification&lt;T&gt; {
  @Override
  public Specification&lt;T&gt; and(Specification&lt;T&gt; other) {
    return new AndSpecification&lt;T&gt;(this, other);
  }

  @Override
  public Specification&lt;T&gt; or(Specification&lt;T&gt; other) {
    return new OrSpecification&lt;T&gt;(this, other);
  }

  @Override
  public Specification&lt;T&gt; not() {
    return new NotSpecification&lt;T&gt;(this);
  }
}
</pre>
<p>Last but not least, we need common implementations for the boolean operators:</p>
<pre class="brush: java;">
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

public class AndSpecification&lt;T&gt; extends AbstractSpecification&lt;T&gt; {
  private final Specification&lt;T&gt; a;
  private final Specification&lt;T&gt; b;

  public AndSpecification(Specification&lt;T&gt; a, Specification&lt;T&gt; b) {
    this.a = a;
    this.b = b;
  }

  @Override
  public boolean isSatisfiedBy(T candidate) {
    return a.isSatisfiedBy(candidate) &amp;&amp; b.isSatisfiedBy(candidate);
  }

  @Override
  public Predicate toPredicate(CriteriaBuilder cb, CriteriaQuery&lt;T&gt; query, Root&lt;T&gt; root) throws UnsupportedOperationException {
    return cb.and(a.toPredicate(cb, query, root), b.toPredicate(cb, query, root));
  }
}
</pre>
<p>One can easily imagine, how the OrSpecification and the NotSpecification look like.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adrianhummel.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adrianhummel.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adrianhummel.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=138&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adrianhummel.wordpress.com/2011/07/11/specification-using-jpa-2-0-criteria-api-source-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bdaed8f70b94fb4e077f375f14e5c01c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">adrianhummel</media:title>
		</media:content>
	</item>
		<item>
		<title>Composed Specifications using JPA 2.0</title>
		<link>http://adrianhummel.wordpress.com/2010/07/02/composed-specifications-using-jpa-2-0/</link>
		<comments>http://adrianhummel.wordpress.com/2010/07/02/composed-specifications-using-jpa-2-0/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 12:52:04 +0000</pubDate>
		<dc:creator>adrianhummel</dc:creator>
				<category><![CDATA[Analysis]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Trivadis]]></category>
		<category><![CDATA[Pattern]]></category>

		<guid isPermaLink="false">http://adrianhummel.wordpress.com/?p=99</guid>
		<description><![CDATA[Let&#8217;s assume we want to build an application for a soccer talent scout. The entity of interest is player. The domain layer provides a repository in order to manage and access players. The PlayerRepository defines two finder methods: Now your customer adds a new requirement: &#8220;I need a list of all players who are fair [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=99&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s assume we want to build an application for a soccer talent scout. The entity of interest is player. The domain layer provides a repository in order to manage and access players.</p>
<p>The PlayerRepository defines two finder methods:</p>
<pre class="brush: java;">
public interface PlayerRepository {
  public List&lt;Player&gt; findFairPlayers();
  public List&lt;Player&gt; findBonusEligiblePlayers();
}
</pre>
<p>Now your customer adds a new requirement: &#8220;I need a list of all players who are fair <em>and</em> bonus eligible!&#8221;. Invoking both existing methods and selecting the relevant players manually is not a good idea (not reusable, results in two database queries). Thus, this typically results in another finder method:</p>
<pre class="brush: java;">
public interface PlayerRepository {
  public List&lt;Player&gt; findFairPlayers();
  public List&lt;Player&gt; findBonusEligiblePlayers();
  public List&lt;Player&gt; findFairAndBonusEligiblePlayers();
}
</pre>
<p>One can imagine that the complexity quickly increases and the DRY principle is violated.</p>
<p>Yesterday, Mischa Kölliker and I gave a talk about <a title="Rich Domain Model using JPA 2.0 (in German)" href="http://www.java-forum-stuttgart.de/abstracts.html#D1" target="_blank">Rich Domain Model using JPA 2.0</a> at the <a title="Java Forum Stuttgart" href="http://www.java-forum-stuttgart.de" target="_blank">Java Forum Stuttgart</a> where we combined the specification pattern described by <a title="Domain Driven Design" href="http://domaindrivendesign.org/books" target="_blank">Eric Evans</a> with the Criteria API introduced in JPA 2.0. This means that the resulting interface will look like this:</p>
<pre class="brush: java;">
public interface PlayerRepository {
  public List&lt;Player&gt; findAll(Specification&lt;Player&gt; specification);
}
</pre>
<p>The three finder methods have been reduced to one generic findAll method. The findAll method accepts a specification parameter which &#8211; as its name implies &#8211; specifies <strong>what </strong>the repository must select.</p>
<p>The concrete implementation uses JPA 2.0 Criteria API:</p>
<pre class="brush: java; highlight: [7];">
public class JPAPlayerRepository implements PlayerRepository {
  public List&lt;Player&gt; findAll(Specification&lt;Player&gt; specification) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery&lt;Player&gt; q = cb.createQuery(Player.class);
    Root&lt;Player&gt; player = q.from(Player.class);

    q.where(specification.toPredicate(cb, q, player));

    return em.createQuery(q).getResultList();
  }
}
</pre>
<pre class="brush: java;">
public class FairPlayerSpecification implements Specification&lt;Player&gt; {

  private static final int NUMBER_OF_CARDS = 5;
  private int season = 0;

  public FairPlayerSpecification(int season) {
    this.season = season;
  }

  @Override
  public Predicate toPredicate(
    CriteriaBuilder cb, CriteriaQuery&lt;Player&gt; q, Root&lt;Player&gt; player) {

    Subquery&lt;Long&gt; sq = q.subquery(Long.class);
    Root&lt;Card&gt; card = sq.from(Card.class);

    sq.where(cb.and(cb.equal(card.get(Card_.player), player),
    cb.equal(card.get(Card_.season), this.season)));

    return cb.lt(sq.select(cb.count(card)), NUMBER_OF_CARDS);
  }

  //...
}
</pre>
<p>The repository delegates the <strong>where </strong>clause to the specification which transforms itself into a valid JPA 2.0 predicate object. A predicate is just a boolean expression which can be true or false.</p>
<p>This approach shows its strengths best when composing specifications. For example: the talent scout wants to find all his &#8220;problem children&#8221; who are specified as follows:</p>
<ul>
<li>unfair <em>OR </em>not bonus eligible      <em>AND</em></li>
<li>long running contract</li>
</ul>
<p>The corresponding code looks like this:</p>
<pre class="brush: java;">
Specification&lt;Player&gt; unfair;
Specification&lt;Player&gt; notBonusEligible;
Specification&lt;Player&gt; longRunningContract;
Specification&lt;Player&gt; problemChild;

unfair = new FairPlayerSpecification(2009).not();
notBonusEligbile = new BonusEligbileSpecification().not();
longRunningContract = new LongRunningContractSpecification();

problemChild = longRunningContract.and(unfair.or(notBonusEligible));
</pre>
<p>One may argue that combining specifications with Criteria API mixes up business and technical aspects. In the above example this is certainly true, especially when you need to abstract away from your technology (here JPA). On the other hand you should always look for a pragmatic and cohesive solution&#8230; and we think this is a possible approach to start with.</p>
<p>Would be great to hear about your experiences implementing composed specifications using O/R mapping technologies (especially JPA 2.0).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adrianhummel.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adrianhummel.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adrianhummel.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=99&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adrianhummel.wordpress.com/2010/07/02/composed-specifications-using-jpa-2-0/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bdaed8f70b94fb4e077f375f14e5c01c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">adrianhummel</media:title>
		</media:content>
	</item>
		<item>
		<title>Delve into the Rich Test Model</title>
		<link>http://adrianhummel.wordpress.com/2010/04/29/delve-into-the-rich-test-model/</link>
		<comments>http://adrianhummel.wordpress.com/2010/04/29/delve-into-the-rich-test-model/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 19:34:38 +0000</pubDate>
		<dc:creator>adrianhummel</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Trivadis]]></category>
		<category><![CDATA[Pattern]]></category>
		<category><![CDATA[Rich Test Model]]></category>

		<guid isPermaLink="false">http://adrianhummel.wordpress.com/?p=58</guid>
		<description><![CDATA[The previous post introduced the concept of the Rich Test Model. This article shows the source code of the model and how it can be enriched with further behavior in order to support more test scenarios. The TransferTestModel source code looks like this: This class follows the Builder pattern and consists of three parts: The [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=58&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://adrianhummel.wordpress.com/2010/03/26/rich-test-model/">previous post</a> introduced the concept of the <strong>Rich Test Model</strong>. This article shows the source code of the model and how it can be enriched with further behavior in order to support more test scenarios.</p>
<p>The TransferTestModel source code looks like this:</p>
<pre class="brush: java;">
public class TransferTestModel {
  private Account debitAccount;
  private Account creditAccount;
  private Date transferDate;
  private Money transferAmount;

  private TransferTestModel() {} // not instantiable

  public static TransferTestModel startTransferFromPrivateAccount() {
    return new TransferTestModel() {
      {
        debitAccount = new PrivateAccount(
          &quot;1122334455&quot;, new Money(&quot;CHF&quot;, 5000));
      }
    }
  }

  public TransferTestModel toForeignBankAccount() {
    creditAccount = new GenericBankAccount(
      &quot;9988776655&quot;, new Address(&quot;Money Receiver&quot;, &quot;1234&quot;, &quot;Somewhere&quot;));
    return this;
  }

  public TransferTestModel asSoonAsPossible() {
    transferDate = DateUtils.nextBusinessDay();
    return this;
  }

  public TransferTestModel amountGreaterThanAvailableMoney() {
    transferAmount = debitAccount.getBalance().add(1);
    return this;
  }

  public Transfer build() {
    return new Transfer(
      creditAccount, debitAccount, transferDate, transferAmount);
  }
}
</pre>
<p>This class follows the <a title="Builder pattern" href="http://books.google.ch/books?id=ka2VUBqHiWkC&amp;lpg=PP1&amp;pg=PA11#v=onepage&amp;q&amp;f=false" target="_blank">Builder pattern</a> and consists of three parts:</p>
<ol>
<li>The static (factory) method startTransferFromPrivateAccount starts the build process. <em>(mandatory data)</em></li>
<li>The three member methods toForeignBankAccount, asSoonAsPossible, and amountGreaterThanAvailableMoney define the transfer details. <em>(optional data)</em></li>
<li>The build method finishes the build process and returns the Transfer object.</li>
</ol>
<p>Even though the TransferTestModel has only one static and three member methods, it already supports eight different test scenarios:</p>
<blockquote><p>= &lt;number of static methods&gt; * (2 ^ &lt;number of member methods&gt;)</p></blockquote>
<p>By adding</p>
<ul>
<li>new static factory methods (e.g. for account types applying different business rules) and</li>
<li>new member methods (e.g. for further business aspects, threshold testing, or special cases which need complex initializations),</li>
</ul>
<p>the model will be enriched  and more test scenarios are possible.</p>
<p>Assume we want to test transfers from a savings account (with a different &#8220;available money&#8221; policy), transfers scheduled on a weekend day, and transfers scheduled in the past. Let&#8217;s see how the model will be expanded&#8230;</p>
<pre class="brush: java;">
public class TransferTestModel {
  public static TransferTestModel startTransferFromSavingsAccount() {
    return new TransferTestModel() {
      {
        debitAccount = new SavingsAccount(
          &quot;12356789&quot;, new Money(&quot;CHF&quot;, 150000));
      }

      @Override
      public TransferTestModel amountGreaterThanAvailableMoney() {
        // a maximum of CHF 50'000 can be transferred
        // from a savings account
        transferAmount = new Money(&quot;CHF&quot;, 50001);
        return this;
      }
    }
  }

  public TransferTestModel onWeekendDay() {
    Calendar cal = Calendar.getInstance();
    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
    int offset = Math.min(1, Calendar.SATURDAY - dayOfWeek);
    cal.add(Calendar.DAY_OF_MONTH, offset);
    transferDate = cal.getTime();
    return this;
  }

  public TransferTestModel inThePast() {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DAY_OF_MONTH, -1);
    transferDate = cal.getTime();
    return this;
  }

  // snipped code of first sample (see above)
}
</pre>
<p>The startTransferFromSavingsAccount method initializes a transfer using a savings account and overrides the default amountGreaterThanAvailableMoney method. Of course, a real-life test model would not use hardcoded amounts and  policy rules (as used in the example above) but would rather delegate this to the business layer.</p>
<p>By overriding the default implementation, the static factory method defines and therefore encapsulates the (context bound) test behavior.  A unit test based on this new method does not care about these details:</p>
<pre class="brush: java; highlight: [8];">
public class TransferServiceTest {
  @Test
  public void testTransferUsingInvalidAmount() {
    Transfer transfer = TransferTestModel
      .startTransferFromSavingsAccount()
      .toForeignBankAccount()
      .asSoonAsPossible()
      .amountGreaterThanAvailableMoney()
      .build();

    Transaction transaction = transferService.transfer(transfer);
    // Assert expected transaction details
  }
}
</pre>
<p>This test only denotes that it wants to transfer an &#8220;invalid&#8221; amount but does not know what &#8220;invalid&#8221; means in terms of a savings account &#8211; this knowledge is hidden in the test model.</p>
<p><strong>Outlook</strong></p>
<p>A further article will focus on test assertions and method naming&#8230; stay tuned!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adrianhummel.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adrianhummel.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adrianhummel.wordpress.com/58/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=58&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adrianhummel.wordpress.com/2010/04/29/delve-into-the-rich-test-model/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bdaed8f70b94fb4e077f375f14e5c01c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">adrianhummel</media:title>
		</media:content>
	</item>
		<item>
		<title>Rich Test Model</title>
		<link>http://adrianhummel.wordpress.com/2010/03/26/rich-test-model/</link>
		<comments>http://adrianhummel.wordpress.com/2010/03/26/rich-test-model/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 13:22:15 +0000</pubDate>
		<dc:creator>adrianhummel</dc:creator>
				<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Trivadis]]></category>
		<category><![CDATA[Pattern]]></category>
		<category><![CDATA[Rich Test Model]]></category>

		<guid isPermaLink="false">http://adrianhummel.wordpress.com/?p=41</guid>
		<description><![CDATA[Introduction How do you manage complex test scenarios especially the variety of parameters, entities, and their interdependencies? What are your experiences maintaining these test cases? According to my experience, writing automated tests does not implicitly mean that these tests are useful and maintainable. Furthermore, writing tests for a complex domain can become a pretty tricky [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=41&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>How do you manage complex test scenarios especially the variety of parameters, entities, and their interdependencies? What are your experiences maintaining these test cases?</p>
<p>According to my experience, writing automated tests does not implicitly mean that these tests are useful and maintainable. Furthermore, writing tests for a complex domain can become a pretty tricky task. A lot of test methods are full of cumbersome (and itself error-prone) initialization code to build the test parameters and to invoke the methods under test.</p>
<p>This article shows the drawbacks of a hard coded, naïve test approach and proposes a &#8220;rich test model&#8221; to address those issues.</p>
<p><strong>Test at first feel</strong></p>
<p>Let&#8217;s transfer some money and test the transfer service:</p>
<pre class="brush: java;">
public class TransferServiceTest {
  @Test
  public void testTransferWithInvalidAmount() {
    Transfer transfer = new Transfer();
    transfer.setDebitAccount(&quot;1122334455&quot;);
    transfer.setCreditAccount(&quot;9988776655&quot;,
      new Address(&quot;Money Receiver&quot;, &quot;1234&quot;, &quot;Somewhere&quot;));
    transfer.setTransferDate(new Date());
    transfer.setAmount(&quot;EUR&quot;, 1000);

    Transaction transaction = transferService.transfer(transfer);
    // assert expected transaction details ...
  }
}
</pre>
<p>There are some issues with this approach:</p>
<ol>
<li>Explicit      interdependencies.<br />
The explicit usage of account numbers, address data, date, and amount      requires detailed knowledge about the data structures and their relationships.      Replacing the hard coded values by constants would not solve the problem      as we still need to know which values suit together for this test scenario.</li>
<li>Complicated      threshold value testing.<br />
Since the transfer amount and date are explicitly set, threshold value      testing becomes cumbersome. Assume you want to test the following      scenarios: the transfer amount is 1) lower, 2) equal, and 3) greater than      the currently available money. You will need to know the type of account &#8220;1122334455&#8243;,      the current balance and the allowed overdraw policy of this account. This      is too much information for such a simple example.</li>
<li>Violated DRY      principle.<br />
If different test scenarios are based on the same test data set, we run      the risk of violating the DRY (don’t repeat yourself) principle because      the &#8220;knowledge&#8221; of these data interdependencies is spread all over the      tests.</li>
<li>Maintenance hell.<br />
Automated tests are an essential key factor for successful projects. At first feel, automated tests seem to behave nicely. But if you need to change those tests – and this happens – they can show their true colors. What happens if interdependencies change, or if new business rules affect all your tests? In the worst case you have to change hundreds of test scenarios.</li>
</ol>
<p>This rule addresses the aforementioned issues:</p>
<blockquote><p>Test methods must express <em><strong>what </strong></em>they test, not <strong><em>how </em></strong>they test.</p></blockquote>
<p><strong>Separate test method from the model</strong></p>
<p>Let&#8217;s change the above code snippet a little bit:</p>
<pre class="brush: java;">
public class TransferServiceTest {
  @Test
  public void testTransferUsingInvalidAmount() {
    Transfer transfer = TransferTestModel
      .startTransferFromPrivateAccount()
      .toForeignBankAccount()
      .asSoonAsPossible()
      .amountGreaterThanAvailableMoney()
      .build();

    Transaction transaction = transferService.transfer(transfer);
    // Assert expected transaction details
  }
}
</pre>
<p>This code is the result of a strict separation of concerns (SoC). The test method just describes <strong><em>what</em></strong> it wants to test: a transfer from a private account to a foreign bank account, transfer the money as soon as possible, and use an amount which is greater than the available money.</p>
<p>All the transfer details (account numbers, addresses, exact date and amount) are abstracted and hidden in the TransferTestModel class. The TransferTestModel class follows the builder pattern and knows the domain internals and <strong><em>how</em></strong> to parameterize the test data. This builder class represents a test model with rich behavior. I therefore call it a &#8220;<strong>rich test model</strong>&#8220;.</p>
<p><strong>Conclusions</strong></p>
<p>Effective tests focus on <strong><em>what</em></strong> to test. Technical details and data interdependencies should be abstracted and hidden in a rich test model based on the domain under test. The resulting rich test model builds a (test-driven) DSL and is therefore an ideal discussion basis for developers, testers, and domain experts.</p>
<p>The separation of concerns (rich test model and test scenario) allows to successfully manage data interdependencies and to minimize the maintenance effort.</p>
<p><strong>Outlook</strong></p>
<p>In future articles I will show the details of the TransferTestModel class, enrich the model in order to support more sophisticated tests, and emphasize the importance of the ubiquitous language in the rich test model.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adrianhummel.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adrianhummel.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adrianhummel.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=41&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adrianhummel.wordpress.com/2010/03/26/rich-test-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bdaed8f70b94fb4e077f375f14e5c01c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">adrianhummel</media:title>
		</media:content>
	</item>
		<item>
		<title>New blog</title>
		<link>http://adrianhummel.wordpress.com/2010/03/22/new-blog/</link>
		<comments>http://adrianhummel.wordpress.com/2010/03/22/new-blog/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 20:26:14 +0000</pubDate>
		<dc:creator>adrianhummel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[This is my new blog about Java and software (design) issues. I try to cover a wide range of topics throughout the whole SDLC, focussing on lessons learned gained from my work as a Java consultant.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=1&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is my new blog about Java and software (design) issues. I try to cover a wide range of topics throughout the whole SDLC, focussing on lessons learned gained from my work as a Java consultant.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adrianhummel.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adrianhummel.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adrianhummel.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adrianhummel.wordpress.com&amp;blog=12751032&amp;post=1&amp;subd=adrianhummel&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adrianhummel.wordpress.com/2010/03/22/new-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bdaed8f70b94fb4e077f375f14e5c01c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">adrianhummel</media:title>
		</media:content>
	</item>
	</channel>
</rss>
