<?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:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dahlia Bock</title>
	<atom:link href="http://dahliabock.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dahliabock.wordpress.com</link>
	<description></description>
	<lastBuildDate>Tue, 10 Nov 2009 03:00:54 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='dahliabock.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/1bcdecb66b684b9a3e8d1ca6e602c959?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Dahlia Bock</title>
		<link>http://dahliabock.wordpress.com</link>
	</image>
			<item>
		<title>Book Review: Working Effectively with Legacy Code &#8211; Chapter 6</title>
		<link>http://dahliabock.wordpress.com/2009/11/10/book-review-working-effectively-with-legacy-code-chapter-6/</link>
		<comments>http://dahliabock.wordpress.com/2009/11/10/book-review-working-effectively-with-legacy-code-chapter-6/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 02:40:56 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[coding practices]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=334</guid>
		<description><![CDATA[
&#160;
&#160;
&#160;
&#160;
&#160;
Working Effectively with Legacy Code by Michael Feathers
I&#8217;ve been carrying around this book with me for the past few weeks and I find myself going back and reading parts of a chapter again and again, trying to soak in the concepts. This particular chapter, titled: I Don&#8217;t Have Much Time And I Have To Change [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=334&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a style="float:left;padding-right:20px;" href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"><img src="http://photo.goodreads.com/books/1170271723m/44919.jpg" border="0" alt="Working Effectively with Legacy Code (Robert C. Martin Series)" /></a><a href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code">Working Effectively with Legacy Code by Michael Feathers</a></p>
<p>I&#8217;ve been carrying around this book with me for the past few weeks and I find myself going back and reading parts of a chapter again and again, trying to soak in the concepts. This particular chapter, titled: <em>I Don&#8217;t Have Much Time And I Have To Change It</em>, struck me specifically when Feathers starts out talking about change and how often it happens in code bases and that steps should be taken to make every consequent change easier than the one before. When teams make it a point to only introduce changes to the code only if they have tests to cover that change, they find that their velocity slows down and people feel like they aren&#8217;t getting as much done as they need to. Feathers emphasizes that this is normal but if they persevere, they slowly realize that they are revisiting better code and changes get easier and easier to make.</p>
<p>I think that it&#8217;s important for teams to understand the benefits of testable code and how it eases the process of change so that they will invest the time and energy needed to get the code to that point. And I quote:</p>
<blockquote><p><em>Ultimately, testing makes your work go faster, and that&#8217;s important in nearly every development organization.</em></p></blockquote>
<p>Having code that is testable is only possible if we do one of the following (If I remember correctly, I think this is according to Uncle Bob):</p>
<ol>
<li>Write the tests before writing the code</li>
<li>Design for testability</li>
</ol>
<p>Doing the latter isn&#8217;t easy, and in fact it is so hard to achieve that people end up not doing it at all. So that leaves us with Option 1. But sometimes you come across code that doesn&#8217;t have any tests AND doesn&#8217;t look like it is testable, but you have to make some changes in a short amount of time. So what do you do? Michael Feathers suggests 4 approaches, and my colleague <a href="http://www.markhneedham.com/blog/2009/10/26/book-club-working-effectively-with-legacy-code-chapters-6-7-michael-feathers/" target="_blank">Mark documents it in a short and sweet way</a> (basically he beat me to writing the post first).</p>
<ol>
<li>Sprout Method<br />
Advantages: Separating new code from old code. New code is testable.<br />
Disadvantages: You&#8217;re giving up on the old code for now.</li>
<li>Sprout Class<br />
Advantages: Allows you to move forward with more confidence.<br />
Disadvantages: Conceptual complexity &#8211; moving new code into a separate class disrupts the flow of how key classes in the code base work together.</li>
<li>Wrap Method<br />
Advantages: A great way to introduce seams (this is a concept that Feathers talks about in a previous chapter, which we will visit in a later post) while adding new features.<br />
Disadvantages: This method requires you to rename the method that you want to change, and create a new method with the same name as the previous method before the rename was done. Sometimes this could introduce sloppy method names because we needed to do some renaming to make way for the new method.</li>
<li>Wrap Class<br />
This method is pretty much the same as Wrap Method except you&#8217;re extracting new behavior out into a new class. Feathers mentioned that 2 things push him towards choosing to use Wrap Classes and one of them is when a class has grown so large that he cannot stand to make it worse. Pushing behavior into a new class when the existing class is unmanageably large could also indicate that the original class might have too many responsibilities and thus needs to be gutted.</li>
</ol>
<p>I like this chapter because it formalizes a lot of things that I try to do very often because of the large range of code bases that I work with, but find it difficult to nail it down to something that could be explained to someone else.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/334/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/334/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/334/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/334/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/334/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/334/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/334/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/334/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/334/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/334/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=334&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/11/10/book-review-working-effectively-with-legacy-code-chapter-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>

		<media:content url="http://photo.goodreads.com/books/1170271723m/44919.jpg" medium="image">
			<media:title type="html">Working Effectively with Legacy Code (Robert C. Martin Series)</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing: Unit testing on the UI in Flex (Part 3)</title>
		<link>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-3/</link>
		<comments>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-3/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 03:35:21 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[ThoughtWorks]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=319</guid>
		<description><![CDATA[So how does the view model for the test in my previous post look like? Judging from the test cases written, we would have 3 public methods:

viewModel.valid
viewModel.hasDuplicates
viewModel.save which depends on the first two

public class SomeViewModel
    {
        public var dispatcher:IEventDispatcher;

       [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=319&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So how does the view model for the test in my previous post look like? Judging from the test cases written, we would have 3 public methods:</p>
<ol>
<li>viewModel.valid</li>
<li>viewModel.hasDuplicates</li>
<li>viewModel.save which depends on the first two</li>
</ol>
<pre class="textmate-source blackboard"><span class="source source_actionscript source_actionscript_2"><span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_class meta_class_actionscript meta_class_actionscript_2"><span class="storage storage_type storage_type_class storage_type_class_actionscript storage_type_class_actionscript_2">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_actionscript entity_name_type_class_actionscript_2">SomeViewModel</span></span>
    {
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> dispatcher<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>IEventDispatcher;

        [Bindable]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptions<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection;

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">private</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptionsFromServer<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection; 

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">SomeViewModel</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span> {}

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">addNewSubscription</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">if</span>(subscriptions <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">==</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">null</span>)
                subscriptions <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">new</span> ArrayCollection();

            subscriptions.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(SomeViewModel.createNewViewModel());
        }

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> function <span class="support support_function support_function_actionscript support_function_actionscript_2">get</span> valid()<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="storage storage_type storage_type_actionscript storage_type_actionscript_2">Boolean</span>
        {
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">if</span>(subscriptions <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">==</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">null</span>)
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">return</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">false</span>;

            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">for</span> each(<span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscription<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>SomeViewModel <span class="support support_function support_function_actionscript support_function_actionscript_2">in</span> subscriptions)
            {
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">if</span>(<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">!</span>subscription.valid)
                    <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">return</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">false</span>;
            }
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">return</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">true</span>;
        }

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> function <span class="support support_function support_function_actionscript support_function_actionscript_2">get</span> hasDuplicates()<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="storage storage_type storage_type_actionscript storage_type_actionscript_2">Boolean</span>
        {
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">for</span> each(<span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscription<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>SomeViewModel
                                                 <span class="support support_function support_function_actionscript support_function_actionscript_2">in</span> subscriptions)
            {
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> remainingSubscriptions<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span>
                                             removeFirstOccurenceOf(subscription);
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">if</span>(containsDuplicateValues(remainingSubscriptions, subscription))
                    <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">return</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">true</span>;
            }
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">return</span> <span class="constant constant_language constant_language_actionscript constant_language_actionscript_2">false</span>;
        }

        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">save</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">if</span>(hasChanges <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">&amp;&amp;</span> valid)
            {
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptions<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span>
                         SomeViewModel.convertToDomainModels(subscriptions);
                <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> <span class="support support_function support_function_actionscript support_function_actionscript_2">event</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>SomeEvent <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span>
                         SomeEvent.createSaveSubscriptionsEvent(subscriptions);
                dispatcher.dispatchEvent(<span class="support support_function support_function_actionscript support_function_actionscript_2">event</span>);
            }
        }

    }
</span></pre>
<p>Since <a href="http://mate.asfusion.com/" target="_blank">Mate</a> is event-based, the act of clicking on the &#8216;Save&#8217; button causes the dispatching of an event, and the dispatcher is always the view, which is injected to the View Model via the Controller.</p>
<p>At the end of this, we have the functionality that pertains to the &#8216;Save&#8217; button, but the view doesn&#8217;t need know about these complications. The controller will wire up the &#8216;Save&#8217; button to invoke the save method on the view model, which in turn will only dispatch the event back to the controller if there is a need.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/319/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/319/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/319/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/319/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/319/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/319/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/319/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/319/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/319/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/319/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=319&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing: Unit testing on the UI in Flex (Part 2)</title>
		<link>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-2/</link>
		<comments>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-2/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 02:58:52 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[ThoughtWorks]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=311</guid>
		<description><![CDATA[Continuing on my previous post, say we have the following view:

In this screen, a user is allowed to add a new subscription in the system that s/he cares about, view existing subscriptions, remove existing subscriptions and subsequently save those subscriptions. Let&#8217;s focus on a small portion of the functionality that is outlined in this view. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=311&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Continuing on my previous post, say we have the following view:</p>
<p><img class="aligncenter size-full wp-image-327" title="View" src="http://dahliabock.files.wordpress.com/2009/10/picture-21.png?w=638&#038;h=298" alt="View" width="638" height="298" /></p>
<p>In this screen, a user is allowed to add a new subscription in the system that s/he cares about, view existing subscriptions, remove existing subscriptions and subsequently save those subscriptions. Let&#8217;s focus on a small portion of the functionality that is outlined in this view. When the user adds new subscriptions, saving is only allowed if:</p>
<ol>
<li>All the required fields have been selected</li>
<li>There are no duplicates.</li>
</ol>
<p>So how do we verify that behavior? Forgetting about the view for a moment, let&#8217;s think about the presentation model (I will call it view model) class, which holds the state and logic behind the view. There will be a &#8217;save&#8217; method on that class which will only perform its magic when the view model itself is valid, which means all required fields have been selected, and there aren&#8217;t any duplicate subscriptions. So let&#8217;s write the tests for that behavior:</p>
<pre class="textmate-source blackboard"><span class="source source_actionscript source_actionscript_2">    <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_class meta_class_actionscript meta_class_actionscript_2"><span class="storage storage_type storage_type_class storage_type_class_actionscript storage_type_class_actionscript_2">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_actionscript entity_name_type_class_actionscript_2">SomeViewModelTest</span> <span class="storage storage_modifier storage_modifier_extends storage_modifier_extends_actionscript storage_modifier_extends_actionscript_2">extends</span> <span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_actionscript entity_other_inherited-class_actionscript_2">TestCase</span></span>
    {
        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">shouldNotBeValidIfThereAreNoSubscriptions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given there are no subscriptions
</span>            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertFalse(viewModel.valid);
        }

        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">shouldBeValidWhenAllSubscriptionsAreValid</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given
</span>            viewModel.addNewSubscription();
            viewModel.addNewSubscription();

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>when
</span>            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">for</span> each(<span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscription<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>SomeViewModel <span class="support support_function support_function_actionscript support_function_actionscript_2">in</span> viewModel.subscriptions)
            {
                subscription.<span class="support support_function support_function_actionscript support_function_actionscript_2">type</span> <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.SUBSCRIPTION_TYPE_A;
                subscription.group <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.GROUP_2;
                subscription.priority <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.ACTIONABLE_PRIORITY;
            }

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertTrue(viewModel.valid);
        }

        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">shouldNotBeValidIfOneSubscriptionIsNotValid</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given
</span>            viewModel.addNewSubscription();
            viewModel.addNewSubscription();

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>when
</span>            viewModel.subscriptions[<span class="constant constant_numeric constant_numeric_actionscript constant_numeric_actionscript_2">0</span>].<span class="support support_function support_function_actionscript support_function_actionscript_2">type</span> <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.SUBSCRIPTION_TYPE_A;
            viewModel.subscriptions[<span class="constant constant_numeric constant_numeric_actionscript constant_numeric_actionscript_2">0</span>].group <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.GROUP_1;
            viewModel.subscriptions[<span class="constant constant_numeric constant_numeric_actionscript constant_numeric_actionscript_2">0</span>].priority <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> TestHelper.ACTIONABLE_PRIORITY;

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertFalse(viewModel.valid);
        }

        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">hasDuplicatesShouldReturnTrueIfThereAreDuplicateTypeASubscriptions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given
</span>            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptionsFromServer<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">new</span> ArrayCollection();
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
                createSubscriptionTypeADomainModelWithInformationalPriority());
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
              createSubscriptionTypeBDomainModelWithActionablePriority(TestHelper.GROUP_1));
            viewModel.populateSubscriptionsFromServer(subscriptionsFromServer);

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>when
</span>            viewModel.addNewSubscription();
            viewModel.subscriptions.setItemAt(helper.
                   createSubscriptionTypeADomainModelWithInformationalPriority(), <span class="constant constant_numeric constant_numeric_actionscript constant_numeric_actionscript_2">2</span>);

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertTrue(viewModel.hasDuplicates);
        }

        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">hasDuplicatesShouldReturnTrueIfThereAreDuplicateTypeBSubscriptions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given
</span>            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptionsFromServer<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">new</span> ArrayCollection();
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
                createSubscriptionTypeADomainModelWithInformationalPriority());
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
              createSubscriptionTypeBDomainModelWithActionablePriority(TestHelper.GROUP_1));
            viewModel.populateSubscriptionsFromServer(subscriptionsFromServer);

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>when
</span>            viewModel.addNewSubscription();
            viewModel.subscriptions.setItemAt(helper.
              createSubscriptionTypeBDomainModelWithActionablePriority(TestHelper.GROUP_1), <span class="constant constant_numeric constant_numeric_actionscript constant_numeric_actionscript_2">2</span>);

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertTrue(viewModel.hasDuplicates);
        }

        [Test]
        <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">public</span> <span class="meta meta_function meta_function_actionscript meta_function_actionscript_2"><span class="storage storage_type storage_type_function storage_type_function_actionscript storage_type_function_actionscript_2">function</span> <span class="entity entity_name entity_name_function entity_name_function_actionscript entity_name_function_actionscript_2">hasDuplicatesShouldReturnFalseIfThereAreNoDuplicates</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_actionscript punctuation_definition_parameters_begin_actionscript_2">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_actionscript punctuation_definition_parameters_end_actionscript_2">)</span></span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span><span class="support support_function support_function_actionscript support_function_actionscript_2">void</span>
        {
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>given
</span>            <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">var</span> subscriptionsFromServer<span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">:</span>ArrayCollection <span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_actionscript keyword_operator_symbolic_actionscript_2">=</span> <span class="keyword keyword_control keyword_control_actionscript keyword_control_actionscript_2">new</span> ArrayCollection();
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
                createSubscriptionTypeADomainModelWithInformationalPriority());
            subscriptionsFromServer.<span class="support support_function support_function_actionscript support_function_actionscript_2">addItem</span>(helper.
              createSubscriptionTypeBDomainModelWithActionablePriority(TestHelper.GROUP_1));
            viewModel.populateSubscriptionsFromServer(subscriptionsFromServer);

            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_actionscript comment_line_double-slash_actionscript_2"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_actionscript punctuation_definition_comment_actionscript_2">//</span>then
</span>            assertFalse(viewModel.hasDuplicates);
        }

    }
}
</span></pre>
<p>The view model has 2 attributes that are used to determine whether subscriptions can be saved or not: <em>valid</em> and <em>hasDuplicates</em>. Next we&#8217;ll take a look at the view model itself and how it ties back to the view.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/311/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=311&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/10/29/testing-unit-testing-on-the-ui-in-flex-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>

		<media:content url="http://dahliabock.files.wordpress.com/2009/10/picture-21.png" medium="image">
			<media:title type="html">View</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing: Unit testing on the UI in Flex (Part 1)</title>
		<link>http://dahliabock.wordpress.com/2009/10/28/testing-unit-testing-on-the-ui-in-flex-part-1/</link>
		<comments>http://dahliabock.wordpress.com/2009/10/28/testing-unit-testing-on-the-ui-in-flex-part-1/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 01:48:01 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[UI]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=305</guid>
		<description><![CDATA[I seem to be obsessed with testing lately and after watching J.B. Rainsberger&#8217;s video, I feel even more convinced that good developer testing plays a big part in producing code that is maintainable and not adverse to change in addition to providing the assurance to the developer that a functionality is done when they say [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=305&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I seem to be obsessed with testing lately and after watching <a href="http://www.infoq.com/presentations/integration-tests-scam" target="_blank">J.B. Rainsberger&#8217;s video</a>, I feel even more convinced that good developer testing plays a big part in producing code that is maintainable and not adverse to change in addition to providing the assurance to the developer that a functionality is <em>done</em> when they say it is.</p>
<p>Testing UI code is often a challenge and most projects I&#8217;ve been on defer that to acceptance tests that are driven from the browser. I&#8217;m not disregarding browser tests entirely but like I&#8217;ve mentioned in my <a href="http://dahliabock.wordpress.com/2009/10/24/testing-take-that-log-out-of-your-eye-before-you-can-spot-the-speck-in-your-neighbors-eye/" target="_blank">previous post</a>, that could be a suboptimal testing option.</p>
<p><a href="http://mate.asfusion.com/" target="_blank">Mate</a> (pronounced Mah-tay), which is a tag-based Flex framework, provides the ability to define a separation between the state and behavior of the presentation of a view <em>and</em> the UI controls of the view itself, thus allowing for extensive unit testing of the UI. Before I delve deeper into how that works, let me talk a little bit about the <a href="http://martinfowler.com/eaaDev/PresentationModel.html" target="_blank">Presentation Model</a> pattern, advocated by Martin Fowler. Given a Model-View-Controller situation, the idea of the pattern is to remove all logic from the view into the presentation model, which is a model class that is part of the presentation (or view). This gives us a few advantages:</p>
<ol>
<li>The view becomes dumb and simple. No logic resides here, just UI components.</li>
<li>The view could potentially be reused to display other data by just switching out the model.</li>
<li>And more importantly, we are now able to test the behavior of the view (i.e. what happens when a button is clicked, are multiple drop-down menus dependent on each other, and if so, how?)</li>
</ol>
<p>We will take a look at how to test the behavior and state of the view in my subsequent posts.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/305/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/305/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/305/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=305&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/10/28/testing-unit-testing-on-the-ui-in-flex-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing: Take that log out of your eye before you can spot the speck in your neighbor&#8217;s eye</title>
		<link>http://dahliabock.wordpress.com/2009/10/24/testing-take-that-log-out-of-your-eye-before-you-can-spot-the-speck-in-your-neighbors-eye/</link>
		<comments>http://dahliabock.wordpress.com/2009/10/24/testing-take-that-log-out-of-your-eye-before-you-can-spot-the-speck-in-your-neighbors-eye/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 20:04:05 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[ThoughtWorks]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=298</guid>
		<description><![CDATA[On one of my previous projects, we started on a story (or functionality) by first writing the acceptance test for it. We had a custom-written BDD (Behavior-Driven-Development)-like tool that drove the test from the browser. I initially found it quite cool that it was set up in a way that it made it easy for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=298&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>On one of my previous projects, we started on a story (or functionality) by first writing the acceptance test for it. We had a custom-written BDD (Behavior-Driven-Development)-like tool that drove the test from the browser. I initially found it quite cool that it was set up in a way that it made it easy for developers to write acceptance tests. One of the downsides of writing these kinds of tests is the slow feedback loop. We of course also wrote unit tests but to verify a particular functionality, we ran the acceptance tests. Over time, the team built up a sizable suite of browser tests and the build started to become so brittle that it was red about 70% of the time. Another downside that we had with those tests was the fact that there were a lot of duplicates. Certain parts of the application were accessed with the same initial flow and each of those tests repeated them, hence slowing down the build even more.</p>
<p>I&#8217;ve recently learned that relying primarily on acceptance tests (or integration tests) isn&#8217;t such a good idea after all, in fact it&#8217;s actually quite a bad idea. In an application with many layers, like most applications are, we have to make sure that every single layer has its own suite of tests that verify behavior regardless of its external collaborators. <a href="http://www.jbrains.ca/" target="_blank">J.B. Rainsberger</a> has an excellent presentation called &#8216;<a href="http://www.infoq.com/presentations/integration-tests-scam" target="_blank">Integration Tests Are A Scam</a>&#8216; in which he explains why integration tests can cause a project more harm than good. He defines integration tests to be tests that pass or fail depending on the correctness of multiple objects with multiple unrelated methods that have multiple pieces of interesting behavior where <em>interesting</em> is complex enough to be tested on its own. Acceptance tests are a level of abstraction higher than integration tests, therefore increasing in complexity and number of points of possible failure.</p>
<p>Besides slow feedback, why else would you NOT want to write too many acceptance/integration tests? Say you have an application that is structured in the following way:</p>
<p><img class="aligncenter size-full wp-image-300" title="Layers of an application" src="http://dahliabock.files.wordpress.com/2009/10/layers-of-application1.png?w=534&#038;h=233" alt="Layers of an application" width="534" height="233" /></p>
<p>This is a typical set up of most projects that I&#8217;ve been on. Say for example that you have tests that run on the repository layer but depend heavily on data being in the database, and if the data changes or if the structure of the database changes, you will definitely have broken tests. But you say, &#8220;<em>Each test that runs against the database sets up and tears down data that&#8217;s pertinent to that test only. And we recreate the database at every run of the build. So the database could be empty for all we care about</em>.&#8221; Okay, that&#8217;s all good and fair, but are you going to write ALL your tests for the repository <em>against</em> the database? How many different permutations of those tests can you come up with that would test everything exhaustively? And if you are able to list all those permutations, how long do you think those tests will take to run?</p>
<p>Let&#8217;s take this scenario further. You have tests at the repository layer that depend on the database, and then tests at the service layer that depend on the repository layer. Your development team does not have complete control over the database and its data. It changes under your feet a lot and the build is broken almost all the time and the team does not have enough bandwidth and energy to keep fixing them. Then someone says, &#8220;<em>We need to drive tests from the UI as well</em>!&#8221;. Let&#8217;s take a look at how that would look:</p>
<p><img class="aligncenter size-full wp-image-302" title="Layers of application with broken tests" src="http://dahliabock.files.wordpress.com/2009/10/layers-of-application-with-arrows.png?w=534&#038;h=352" alt="Layers of application with broken tests" width="534" height="352" /></p>
<p>As my colleague Prem has said many times, &#8220;<em>How much hope do the tests driven from the UI will have of passing if everything underneath it is failing?</em>&#8220;. Not only are you introducing tests that take longer to run, you&#8217;re also increasing the number of tests that will continue to fail thus making the lives of developers even harder.</p>
<p>I&#8217;ve learned that developers need to focus more on tests that are:</p>
<ol>
<li>Fast, lightning fast.</li>
<li>Independent of external collaborators, and thus less brittle and prone to breakage because of something other than behavior change in the code immediately under test.</li>
<li>Exhaustive. Since they are fast to begin with, we can write as many tests for as many given scenarios as we can think of.</li>
</ol>
<p>Change is inevitable. And to support change, developers need to be able to move nimbly. Writing tests in a focused manner at the unit level reinforces that nimbleness and allow developers to work more effectively.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/298/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=298&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/10/24/testing-take-that-log-out-of-your-eye-before-you-can-spot-the-speck-in-your-neighbors-eye/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>

		<media:content url="http://dahliabock.files.wordpress.com/2009/10/layers-of-application1.png" medium="image">
			<media:title type="html">Layers of an application</media:title>
		</media:content>

		<media:content url="http://dahliabock.files.wordpress.com/2009/10/layers-of-application-with-arrows.png" medium="image">
			<media:title type="html">Layers of application with broken tests</media:title>
		</media:content>
	</item>
		<item>
		<title>Coding tip to self</title>
		<link>http://dahliabock.wordpress.com/2009/09/17/coding-tip-to-self/</link>
		<comments>http://dahliabock.wordpress.com/2009/09/17/coding-tip-to-self/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 22:40:51 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[coding practices]]></category>
		<category><![CDATA[ramble]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=294</guid>
		<description><![CDATA[Always leave your codebase in a better (or same, if you really can&#8217;t make it better) condition that it was in before, never worse. Disregard for this rule is how codebases disintegrate, rot and die.
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=294&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Always leave your codebase in a better (or same, if you really can&#8217;t make it better) condition that it was in before, never worse. Disregard for this rule is how codebases disintegrate, rot and die.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/294/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=294&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/09/17/coding-tip-to-self/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
		<item>
		<title>Why one should not live without tests</title>
		<link>http://dahliabock.wordpress.com/2009/09/16/why-one-should-not-live-without-tests/</link>
		<comments>http://dahliabock.wordpress.com/2009/09/16/why-one-should-not-live-without-tests/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 02:13:12 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=289</guid>
		<description><![CDATA[I find it hard to imagine myself writing any sort of code without a test to back it up. But I&#8217;ve learned that not everyone shares that sentiment. So here&#8217;s an attempt to explain why developer tests are extremely vital to reliable and working software.
[Disclaimer]: These are not my thoughts alone. They have been collated [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=289&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I find it hard to imagine myself writing any sort of code without a test to back it up. But I&#8217;ve learned that not everyone shares that sentiment. So here&#8217;s an attempt to explain why <strong>developer tests</strong> are extremely vital to reliable and working software.</p>
<p><strong>[Disclaimer]</strong>: These are not my thoughts alone. They have been collated from a number of books and blogs that I&#8217;ve read over the months. A few of which are <a href="http://dahliabock.wordpress.com/2009/04/20/book-review-clean-code-a-handbook-of-agile-software-craftmanship/" target="_blank">Clean Code by Robert Martin</a> and <a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052" target="_blank">Working Effectively with Legacy Code by Michael Feathers</a>.</p>
<p><strong>[Yet another disclaimer]</strong>: My colleague Pat Kua reminded me that I should avoid blanket statements that say developers should write tests all the time. Thanks Pat! He writes about when tests should and should not be written <a href="http://www.thekua.com/atwork/2008/02/if-you-do-test-driven-development-all-the-time-youre-doing-something-wrong/" target="_blank">here</a>. So I should say that I&#8217;m talking specifically about developers writing production code in a focused mode with a good idea of how the resulting code should behave. And I&#8217;m not even bringing up Test Driven Development, but just the fact that having tests as an assurance that what you&#8217;ve written behaves in the way you expect and having that assurance continuously going forward.</p>
<p><em><strong>1. </strong></em><em><strong>Getting fast feedback</strong></em><br />
When you write a piece of functionality on a web application for example, arguably you could launch the application, drill down to where the code that you wrote is executed and test whether it behaves the way you expect it to. One of the problems with that approach is that the feedback loop is large. Depending on how your development environment is set up, it might take a whole 10 minutes (or more) to bring up the application on the browser, login (if you have to), drill down to the part of the application that you&#8217;re interested in and finally test its functionality. With a test, you could run it, and it would probably take 5% (or much less) of that 10 minutes to execute and tell you whether your code behaves the way you think it should. Different types of tests have different levels of feedback loops.</p>
<p>The lowest level of tests you can write are <strong>unit tests</strong> &#8211; these test the behavior of the lowest unit of code that you can have, which is usually a class. These tests should run extremely fast i.e. you could execute a few hundred of them in a matter of seconds. Then there are <strong>integration tests</strong> that test interaction between two or more components, these could involve database or file system access. These could potentially take longer to run since they interact with agents outside your application and should be written with care as to not increase the build time unnecessarily. <strong>Functional or acceptance tests</strong> come next. These are usually written against your application as a whole (i.e. through the browser) and should test features of the application on a higher level and mimic the interaction of a user with your application. These tests typically take the longest to run.</p>
<p><em><strong>2. Tests document your code<br />
</strong></em>This brings up yet another debate about how the functionality of an application should be documented for the users or future consumers of the code. As a developer, the best documentation of an application is always the tests. If I want to know what a class is supposed to do and how it&#8217;s supposed to behave, if there was a test, I could take a look at that and in theory, understand what I need to know in a relatively short time as opposed to trying to understand the code. Tests acting as documentation also beats external documentation because if a functionality changes, Word or PDF documents describing that change don&#8217;t always get updated and with time developers will lose visibility into how exactly the code should behave.</p>
<p><strong><em>3. Gives you confidence to change your code</em></strong><br />
I often hear developers say things like, &#8220;I&#8217;m afraid to make that change there because I don&#8217;t know what will break after that&#8221;. That doesn&#8217;t mean that the particular developer is incompetent of understanding what the code is supposed to but it&#8217;s a symptom of a bigger problem which is the fact that there is no assurance whether a change we make in one portion of the application will not break a functionality in another portion. In his book, Working Effectively With Legacy Code, Michael Feathers points out that tests are <em>&#8220;kind of like  a cloak we put over code we are working on to make sure that bad changes don&#8217;t leak out and infect the rest of our software. When we have a good set of tests around a piece of code, we can make changes and find out quickly whether the effects were good or bad&#8221;</em>.</p>
<p>A lot of times there is a steep ramp up for us to be able to get to the point where we can write any kind of test. For example if our code base was in a condition where there is tight coupling everywhere, or there aren&#8217;t clear-cut components that are testable. These impediments would seem to indicate that writing tests would be a waste of time and that we should focus our energies on producing new functionality. Then what I would suggest you do is take a step back and evaluate your priorities.</p>
<p>Would you rather:</p>
<ol>
<li>Spend a chunk of time now reorganizing your code and making it testable, so that you can reap the benefits of having the assurance that whatever you have built still works and will continue to work, and know that whatever that you are currently building or will build in the future will fail faster so that you can fix it and move on.</li>
<li>OR, having to go back and forth every time new functionality is built or when changes are made in existing functionality to make sure that they all still work as they should.</li>
</ol>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/289/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=289&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/09/16/why-one-should-not-live-without-tests/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
		<item>
		<title>Mocking: Mockito vs EasyMock example</title>
		<link>http://dahliabock.wordpress.com/2009/08/21/mocking-mockito-vs-easymock-example/</link>
		<comments>http://dahliabock.wordpress.com/2009/08/21/mocking-mockito-vs-easymock-example/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 21:22:14 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[coding practices]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[mocking]]></category>
		<category><![CDATA[mocking framework]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=282</guid>
		<description><![CDATA[Ever since I was introduced to Mockito about a year ago, I&#8217;ve been a big fan. I wrote a couple of posts about it and promised a long, long time ago that I would post an example of a test written in Mockito and one in another mocking framework. The lucky chosen one was EasyMock. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=282&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Ever since I was introduced to <a href="http://mockito.org/" target="_blank">Mockito</a> about a year ago, I&#8217;ve been a big fan. I wrote a <a href="http://dahliabock.wordpress.com/2008/11/10/drink-that-mockito-part-1/" target="_blank">couple</a> of <a href="http://dahliabock.wordpress.com/2009/04/21/an-interesting-blog-post-about-mockito-and-other-mocking-frameworks/" target="_blank">posts</a> about it and promised a long, long time ago that I would post an example of a test written in Mockito and one in another mocking framework. The lucky chosen one was <a href="http://easymock.org/" target="_blank">EasyMock</a>. My biggest plugs for Mockito would be:</p>
<ol>
<li>Test readability. Mockito tests are more concise and it discourages noise in test code.</li>
<li>The ability to clearly distinguish test expectations from test verifications so that you know what exactly you&#8217;re stubbing and what you&#8217;re testing.</li>
</ol>
<p>Here&#8217;s an example of a class that I want to test: <code>ProfileService.java</code>. NOTE: Please ignore the design of the code itself. Let&#8217;s just say that all I wanted to do was to test it&#8217;s behavior without changing it. And I do know that it&#8217;s not the best, in fact far from the best.</p>
<p>There is one method in that class which retrieves a Profile from the database and finds all the contacts associated with that profile and goes through all of them and if there is an application in a contact that is already Closed, an exception is thrown and I&#8217;m not allowed to close the profile. Otherwise, the status of the profile is changed to Closed and this is updated in the database through the repository.</p>
<p style="text-align:center;"><img class="aligncenter" title="ProfileService.java" src="../files/2009/08/picture-1.png" alt="ProfileService.java" width="700" height="321" /></p>
<p style="text-align:center;">
<p>Let&#8217;s look at the EasyMock test first.</p>
<p><img class="aligncenter size-full wp-image-284" title="ProfileServiceTestWithEasyMock.java" src="http://dahliabock.files.wordpress.com/2009/08/picture-2.png?w=700&#038;h=330" alt="ProfileServiceTestWithEasyMock.java" width="700" height="330" /></p>
<p>Notice that test verifications, i.e. that profileRepository.updateProfile() was called at the end, are interchanged with test expectations, thus blurring the line between what you&#8217;re setting up and what you&#8217;re testing.</p>
<p>Now let&#8217;s check out the Mockito version of the test.</p>
<p><img class="aligncenter size-full wp-image-285" title="ProfileServiceTestWithMockito.java" src="http://dahliabock.files.wordpress.com/2009/08/picture-3.png?w=700&#038;h=304" alt="ProfileServiceTestWithMockito.java" width="700" height="304" /></p>
<p>First thing you should notice is that the test is much shorter, yes, only by a few lines, but it&#8217;s a few lines less confusing. The test is also easier to break into a logical given-when-then BDD-style scenario. There is also clear distinction between what you&#8217;re stubbing (expectations and setup) and what you&#8217;re actually testing (verifications).</p>
<p>I can&#8217;t see how EasyMock promotes cleaner and clearer tests, I really can&#8217;t.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/282/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/282/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/282/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/282/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/282/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/282/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/282/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/282/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/282/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/282/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=282&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/08/21/mocking-mockito-vs-easymock-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>

		<media:content url="../files/2009/08/picture-1.png" medium="image">
			<media:title type="html">ProfileService.java</media:title>
		</media:content>

		<media:content url="http://dahliabock.files.wordpress.com/2009/08/picture-2.png" medium="image">
			<media:title type="html">ProfileServiceTestWithEasyMock.java</media:title>
		</media:content>

		<media:content url="http://dahliabock.files.wordpress.com/2009/08/picture-3.png" medium="image">
			<media:title type="html">ProfileServiceTestWithMockito.java</media:title>
		</media:content>
	</item>
		<item>
		<title>Test Driven Development &#8211; 10 years later</title>
		<link>http://dahliabock.wordpress.com/2009/08/20/test-driven-development-10-years-later/</link>
		<comments>http://dahliabock.wordpress.com/2009/08/20/test-driven-development-10-years-later/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 02:37:37 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=280</guid>
		<description><![CDATA[Michael Feathers and Steve Freeman have a really good video talking about the phases TDD went through over the last few years. I just want to highlight the summary of their presentation.

Professionals test their code.
And when they say &#8216;test&#8217;, I truly believe they mean writing automated tests. Nothing manual.
Separate what from how.
What you&#8217;re testing should [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=280&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Michael Feathers and Steve Freeman have a really <a href="http://www.infoq.com/presentations/tdd-ten-years-later" target="_blank">good video</a> talking about the phases TDD went through over the last few years. I just want to highlight the summary of their presentation.</p>
<ol>
<li><strong>Professionals test their code</strong>.<br />
And when they say &#8216;test&#8217;, I truly believe they mean writing automated tests. Nothing manual.</li>
<li><strong>Separate <em>what</em> from <em>how.</em></strong><br />
What you&#8217;re testing should be set apart from how you&#8217;re testing it. For example, my colleague Mark recently spoke a little about <a href="http://www.markhneedham.com/blog/2009/08/19/tdd-asserting-on-test-dependency-code/" target="_blank">how setting up a test correctly can sometimes turn into noise and reduce the readability of your tests</a>. One way to avoid the noise is to use Builders.</li>
<li><strong>Automatic tests confirm features.<br />
</strong>I&#8217;ve heard people say things like, &#8220;I had to go back and test some of the features from last iteration because something broke this iteration&#8221;. If we had a suite of automated tests (be it functional, integration or unit), we could avoid situations like that.</li>
<li><strong>It&#8217;s a change in culture.</strong><br />
And it still is, surprisingly. Even after test years, TDD is still a lesser known truth in some organizations. Heck, even the understanding of what a unit test is in shockingly lacking.</li>
<li><strong>&#8220;Working&#8221; isn&#8217;t good enough.</strong><br />
A lot of times we say things like &#8220;I tested the code, and it&#8217;s working.&#8221; So what exactly does &#8216;working&#8217; mean? Does it conform to the business&#8217; expectations? Does it perform well? Another colleague of mine, Phil, wrote about the <a href="http://fragmental.tw/2009/08/17/what-should-techies-care-about/" target="_blank">3 Things Agile Teams Should Care About</a> &#8211; what does it mean to be <em>done</em>?. Let&#8217;s forget about being Agile for a moment and just focus on getting a particular functionality working the way as the business expected <em>consistently</em>.</li>
<li><strong>Listen to the tests.</strong><br />
What should you do if the tests are failing when you run the build? What should you do when the tests fail on the continuous integration build? We should listen to them. Tests are a feedback mechanism. They ensure the integrity of our system and we need to make sure that we pay attention to them at all times.</li>
<li><strong>A working system provides feedback.</strong></li>
<li><strong>Focus on intent.</strong><br />
What is the intent of the test that you&#8217;re writing? Is it expressed clearly in the method name? Are we just testing getters and setters or are we testing the behavior of the code?</li>
<li><strong>When you&#8217;re lost, slow down.</strong></li>
<li><strong>It&#8217;s not only about testing.</strong></li>
<li><strong>Legacy code is code without tests.</strong></li>
<li><strong>Understand the principles behind the practices.</strong><br />
Agile advocates individuals and interactions over processes and tools. Behind every practice is an intent. We should understand the intent first instead of blindly following the practice lest we fall into the trap of using a practice for a sake of using it.</li>
</ol>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/280/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=280&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/08/20/test-driven-development-10-years-later/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
		<item>
		<title>Why I think layer teams are a bad idea</title>
		<link>http://dahliabock.wordpress.com/2009/08/06/why-i-think-layer-teams-are-a-bad-idea/</link>
		<comments>http://dahliabock.wordpress.com/2009/08/06/why-i-think-layer-teams-are-a-bad-idea/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 02:32:05 +0000</pubDate>
		<dc:creator>Dahlia Bock</dc:creator>
				<category><![CDATA[ThoughtWorks]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[teamwork]]></category>

		<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=270</guid>
		<description><![CDATA[So what exactly do I mean by &#8216;layer teams&#8217;? I mean structuring your software development team in such a way that you have a group of developers for each layer (or more), e.g. UI, services, database, etc. So a UI developer is only concerned about one specific part of the application, namely the UI, obviously, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=270&subd=dahliabock&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So what exactly do I mean by &#8216;layer teams&#8217;? I mean structuring your software development team in such a way that you have a group of developers for each layer (or more), e.g. UI, services, database, etc. So a UI developer is only concerned about one specific part of the application, namely the UI, obviously, and the Services developer with the services, and so on and so forth.</p>
<p>Problems that I&#8217;ve seen surfacing from such a setup:</p>
<ol>
<li>There&#8217;s an enormous amount of overhead time spent going back and forth between the different groups when defining interfaces. Maybe it&#8217;s the nature of the teams I&#8217;ve worked with in the past but IMHO this extra time could be spent writing tests that iron out the interactions between the layers.</li>
<li>Then there&#8217;s another chunk of time spent putting those pieces together and making sure they work correctly, i.e. integration.</li>
<li>This causes silos in the development team where only some people know about the UI, others about the back-end services, etc. This discourages developers to step outside their comfort zone to learn another person&#8217;s &#8216;<em>trade</em>&#8216;.</li>
<li><em>Update</em> &gt;&gt;&gt; Introducing specialized teams also increases the amount of distrust between the teams. One example is the database management team holding on to the schema and data for dear life and believing that no developer should have access to change it. Maybe this is common situation across a lot of projects regardless of team setup, but separating the team does decrease their level of trust for each other.</li>
</ol>
<p>What I think is better is to have every developer comfortable with every part of the application, even if it means taking a <em>productivity hit</em> &#8211; as I&#8217;ve heard it being said. Let&#8217;s say I have a story on the wall that says: &#8220;Add item to shopping cart&#8221;. Ideally, a pair of developers would start first by working with the QA to define acceptance criteria and writing the acceptance tests for that feature. (This is a side note to a session at <a href="http://agile2009.com/" target="_blank">Agile 2009 </a>that I&#8217;m very interested in: <a href="http://agile2009.com/node/3205" target="_blank">Where Does Developer Testing End and Tester Testing Begin?</a>. I wish I was able to go.) Then they would implement what is needed to be able to click through on the application to add an item to the shopping cart which eventually ends up in the database.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/270/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&blog=4589287&post=270&subd=dahliabock&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dahliabock.wordpress.com/2009/08/06/why-i-think-layer-teams-are-a-bad-idea/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d0159d75126c53340250cdd16b5469c4?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">dlbock</media:title>
		</media:content>
	</item>
	</channel>
</rss>