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

<channel>
	<title>Virtuous Code &#187; testing</title>
	<atom:link href="http://devblog.avdi.org/tag/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.avdi.org</link>
	<description>&#34;The three virtues of a programmer: laziness, impatience, and hubris&#34; -- Larry Wall</description>
	<lastBuildDate>Fri, 17 May 2013 15:24:41 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>RubyTapas Freebie: The End of Mocking</title>
		<link>http://devblog.avdi.org/2013/04/22/rubytapas-freebie-the-end-of-mocking/</link>
		<comments>http://devblog.avdi.org/2013/04/22/rubytapas-freebie-the-end-of-mocking/#comments</comments>
		<pubDate>Mon, 22 Apr 2013 19:32:32 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[RubyTapas Samples]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[mock-objects]]></category>
		<category><![CDATA[mocking]]></category>
		<category><![CDATA[mockobjects]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=7573</guid>
		<description><![CDATA[At the borders of our systems, mockist testing hits a point of diminishing returns. In this free episode we take a look at when to stop mocking and start integration testing.]]></description>
				<content:encoded><![CDATA[<p>At the borders of our systems, mockist testing hits a point of diminishing returns. In this free episode we take a look at when to stop mocking and start integration testing.</p>
<a href="http://fast.wistia.net/embed/iframe/sugrtlbt7s?autoPlay=true&controlsVisibleOnLoad=true&endVideoBehavior=reset&playerColor=707070&plugin%5BpostRoll-v1%5D%5Blink%5D=http%3A%2F%2Frubytapas.com&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BbackgroundColor%5D=%23f92661&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5Bcolor%5D=%23fff&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BfontFamily%5D=Gill%20Sans%2C%20Helvetica%2C%20Arial%2C%20sans-serif&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BfontSize%5D=36px&plugin%5BpostRoll-v1%5D%5Btext%5D=Want%20more%3F%20Subscribe%20to%20RubyTapas%21&plugin%5Bsocialbar-v1%5D%5Bbuttons%5D=email-download-twitter-reddit-googlePlus-facebook&plugin%5Bsocialbar-v1%5D%5BdownloadType%5D=original&plugin%5Bsocialbar-v1%5D%5BshowTweetCount%5D=true&popover=true&version=v1&videoHeight=450&videoWidth=800&volumeControl=true" class="wistia-popover[height=478,playerColor=707070,width=800]"><img src="http://embed.wistia.com/deliveries/b4ba19ddb3fa8944131c3c6a764708f7bef2c93c.jpg?image_play_button=true&image_play_button_color=707070e0&image_crop_resized=450x253" alt="" /></a>
<script charset="ISO-8859-1" src="http://fast.wistia.com/static/popover-v1.js"></script>
<div class="boilerplate">
Like what you see? This is just a taste of <a href="http://rubytapas.com/?utm_source=devblog&utm_medium=article&utm_campaign=sample">RubyTapas</a>! Sign up today to get three videos a week, along with full source code and transcripts.
<div class="cta ">
<p class="small"><a href="https://rubytapas.dpdcart.com/subscriber/add?plan_id=10&amp;plan_term_id=17&utm_source=devblog&utm_medium=article&utm_campaign=sample">Subscribe Now!</a></p>
</div>
Or <a href="http://rubytapas.com">click here to learn more</a>.
</div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2013/04/22/rubytapas-freebie-the-end-of-mocking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RubyTapas Freebie: Gem Love Part 2</title>
		<link>http://devblog.avdi.org/2013/04/01/rubytapas-freebie-gem-love-part-2/</link>
		<comments>http://devblog.avdi.org/2013/04/01/rubytapas-freebie-gem-love-part-2/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 13:00:16 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[RubyTapas Samples]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[datamapper]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=7558</guid>
		<description><![CDATA[I have a few ongoing miniseries in RubyTapas. In this, the second installment of a miniseries chronicling the creation of a Rubygems plugin and an associated server, I touch on a number of topics including acceptance testing, the shellwords standard &#8230; <a href="http://devblog.avdi.org/2013/04/01/rubytapas-freebie-gem-love-part-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I have a few ongoing miniseries in RubyTapas. In this, the second installment of a miniseries chronicling the creation of a Rubygems plugin and an associated server, I touch on a number of topics including acceptance testing, the <code>shellwords</code> standard library, the TDD rhythm, and the DataMapper ORM.</p>
<a href="http://fast.wistia.net/embed/iframe/xh232o8sie?autoPlay=true&controlsVisibleOnLoad=true&endVideoBehavior=reset&playerColor=707070&plugin%5BpostRoll-v1%5D%5Blink%5D=http%3A%2F%2Frubytapas.com&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BbackgroundColor%5D=%23f92661&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5Bcolor%5D=%23fff&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BfontFamily%5D=Gill%20Sans%2C%20Helvetica%2C%20Arial%2C%20sans-serif&plugin%5BpostRoll-v1%5D%5Bstyle%5D%5BfontSize%5D=36px&plugin%5BpostRoll-v1%5D%5Btext%5D=Want%20more%3F%20Subscribe%20to%20RubyTapas%21&plugin%5Bsocialbar-v1%5D%5Bbuttons%5D=email-download-twitter-reddit-googlePlus-facebook&plugin%5Bsocialbar-v1%5D%5BdownloadType%5D=original&plugin%5Bsocialbar-v1%5D%5BshowTweetCount%5D=true&popover=true&version=v1&videoHeight=450&videoWidth=800&volumeControl=true" class="wistia-popover[height=478,playerColor=707070,width=800]"><img src="http://embed.wistia.com/deliveries/2f976c93329ce73d45be797a7fd844bc17c3093f.jpg?image_play_button=true&image_play_button_color=707070e0&image_crop_resized=450x253" alt="" /></a>
<script charset="ISO-8859-1" src="http://fast.wistia.com/static/popover-v1.js"></script>
<div class="boilerplate">
Like what you see? This is just a taste of <a href="http://rubytapas.com/?utm_source=devblog&utm_medium=article&utm_campaign=sample">RubyTapas</a>! Sign up today to get three videos a week, along with full source code and transcripts.
<div class="cta ">
<p class="small"><a href="https://rubytapas.dpdcart.com/subscriber/add?plan_id=10&amp;plan_term_id=17&utm_source=devblog&utm_medium=article&utm_campaign=sample">Subscribe Now!</a></p>
</div>
Or <a href="http://rubytapas.com">click here to learn more</a>.
</div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2013/04/01/rubytapas-freebie-gem-love-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring database_cleaner with Rails, RSpec, Capybara, and Selenium</title>
		<link>http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/</link>
		<comments>http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 04:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=2620</guid>
		<description><![CDATA[How I avoid finding myself in database bizarro world while testing Rails apps. <a href="http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>If you write Rails code, or any Ruby code that interacts with a database, and you also write automated tests, chances are you have heard of or used the <a href="https://github.com/bmabey/database_cleaner">database_cleaner</a> gem. It&#8217;s a terrific gem that abstracts away the various ORM APIs for getting the DB into a &#8220;blank slate&#8221; state. </p>
<p> Periodically I start a new project using Rails, with RSpec, Capybara, and Selenium for acceptance testing, and a short way into it I find myself banging my head against bizarre inconsistencies with the test database. I&#8217;ll set up some records in the test DB, only to have the Selenium-driven browser-based tests act like those records never existed. Eventually, I&#8217;ll realize what I did wrong and curse my feeble brain for not remembering the last time I solved the same problem. </p>
<p> The problem is always the same: the tests are being wrapped in database transactions, so any code running outside the actual test process (like, say, a server process servicing a Selenium-driven browser request) <em>does not see</em> the database fixture I&#8217;ve so carefully assembled. </p>
<p> I just walked a <a href="http://devblog.avdi.org/pair-programming-services/">pairing</a> client through the same fix, so in the interests of remembering the steps, and hopefully preventing some other folks from tearing their hair out, here are the steps needed. </p>
<p> First of all, and this is very important, go into <code>spec/spec_helper.rb</code> and change this line: </p>
<pre class="src src-ruby">config.use_transactional_fixtures = <span class="org-variable-name">true</span>
</pre>
<p> To: </p>
<pre class="src src-ruby">config.use_transactional_fixtures = <span class="org-variable-name">false</span>
</pre>
<p> This will disable rspec-rails&#8217; implicit wrapping of tests in a database transaction. Without disabling this, none of the following configuration will matter. </p>
<p> Now configure <code>database_cleaner</code>. I usually create a separate file called <code>spec/support/database_cleaner.rb</code> for this. Inside, I put something like this: </p>
<pre class="src src-ruby"><span class="org-type">RSpec</span>.configure <span class="org-keyword">do</span> |config|

  config.before(<span class="org-constant">:suite</span>) <span class="org-keyword">do</span>
    <span class="org-type">DatabaseCleaner</span>.clean_with(<span class="org-constant">:truncation</span>)
  <span class="org-keyword">end</span>

  config.before(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
    <span class="org-type">DatabaseCleaner</span>.strategy = <span class="org-constant">:transaction</span>
  <span class="org-keyword">end</span>

  config.before(<span class="org-constant">:each</span>, <span class="org-constant">:js</span> =&gt; <span class="org-variable-name">true</span>) <span class="org-keyword">do</span>
    <span class="org-type">DatabaseCleaner</span>.strategy = <span class="org-constant">:truncation</span>
  <span class="org-keyword">end</span>

  config.before(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
    <span class="org-type">DatabaseCleaner</span>.start
  <span class="org-keyword">end</span>

  config.after(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
    <span class="org-type">DatabaseCleaner</span>.clean
  <span class="org-keyword">end</span>

<span class="org-keyword">end</span>
</pre>
<p> Let&#8217;s take that step by step. </p>
<pre class="src src-ruby">config.before(<span class="org-constant">:suite</span>) <span class="org-keyword">do</span>
  <span class="org-type">DatabaseCleaner</span>.clean_with(<span class="org-constant">:truncation</span>)
<span class="org-keyword">end</span>
</pre>
<p> This says that before the entire test suite runs, clear the test database out completely. This gets rid of any garbage left over from interrupted or poorly-written tests&mdash;a common source of surprising test behavior. </p>
<pre class="src src-ruby">config.before(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
  <span class="org-type">DatabaseCleaner</span>.strategy = <span class="org-constant">:transaction</span>
<span class="org-keyword">end</span>
</pre>
<p> This part sets the default database cleaning strategy to be transactions. Transactions are very fast, and for all the tests where they <em>do</em> work&mdash;that is, any test where the entire test runs in the RSpec process&mdash;they are preferable. </p>
<pre class="src src-ruby">config.before(<span class="org-constant">:each</span>, <span class="org-constant">:js</span> =&gt; <span class="org-variable-name">true</span>) <span class="org-keyword">do</span>
  <span class="org-type">DatabaseCleaner</span>.strategy = <span class="org-constant">:truncation</span>
<span class="org-keyword">end</span>
</pre>
<p> This line <em>only</em> runs before examples which have been flagged <code>:js =&gt; true</code>. By default, these are the only tests for which Capybara fires up a test server process and drives an actual browser window via the Selenium backend. For these types of tests, transactions won&#8217;t work, so this code overrides the setting and chooses the &#8220;truncation&#8221; strategy instead. </p>
<pre class="src src-ruby">config.before(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
  <span class="org-type">DatabaseCleaner</span>.start
<span class="org-keyword">end</span>

config.after(<span class="org-constant">:each</span>) <span class="org-keyword">do</span>
  <span class="org-type">DatabaseCleaner</span>.clean
<span class="org-keyword">end</span>
</pre>
<p> These lines hook up <code>database_cleaner</code> around the beginning and end of each test, telling it to execute whatever cleanup strategy we selected beforehand. </p>
<p> And that&#8217;s it! </p>
<p> Note that this is all for RSpec, and does not cover Cucumber configuration. </p>
<p> Hopefully this will help someone else out there avoid the frustrations I&#8217;ve run into! </p>
<p> EDIT: A few people have asked me why I don&#8217;t just force all threads to share the same ActiveRecord connection, as demonstrated <a href="https://gist.github.com/470808">in this Gist</a>. A few reasons: </p>
<ul>
<li>Using <code>database_cleaner</code> implies that I want ORM   neutrality. <code>database_cleaner</code> supports ActiveRecord, DataMapper,   MongoMapper, and others. The solution linked above only works for   ActiveRecord.  </li>
<li>It&#8217;s a monkey-patched kludge which will only work so long as AR   refrains from changing its connection-sharing internals. And frankly   I&#8217;m not sure I trust it to work across all Ruby VM and database   combinations (UPDATE: And indeed, I&#8217;ve now seen two different people   say there are race conditions with the current Postgres   adapter). I&#8217;d be more inclined to use it if ActiveRecord had a   published configuration option which was known to work in all   contexts.  </li>
<li>As I stressed above, I&#8217;m careful to set things up so that only the   tests that need them fall back to truncation. Since <code>:js =&gt; true</code>   tests generally don&#8217;t form the bulk of my suite (and since they are   unavoidably slow anyway, due to the overhead of driving a browser),   I&#8217;m not overly concerned about the added overhead. Perhaps if all of   my acceptance tests drove a live browser I&#8217;d be more worried about   it.  </li>
<li>In cases where database truncation <em>is</em> taking up a significant   amount of test time, you can usually speed things up with some   judicious control of which subset of tables get truncated for a   given test. This is something <code>database_cleaner</code> makes pretty   easy. Maybe that would make a good topic for a followup post.  </li>
<li>UPDATE: Oh yeah, and as <a href="https://twitter.com/donaldball/status/241548932415635456">@donaldball points out</a>, sharing a   transaction between test and test server means acceptance tests   don&#8217;t run quite the same as they would in production. Specifically,   they&#8217;ll never trigger <code>after_commit</code> hooks. </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>New maintainer needed for NullDB</title>
		<link>http://devblog.avdi.org/2012/04/13/new-maintainer-needed-for-nulldb/</link>
		<comments>http://devblog.avdi.org/2012/04/13/new-maintainer-needed-for-nulldb/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 17:45:18 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[nulldb]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=2237</guid>
		<description><![CDATA[NullDB, for those who don&#8217;t know, is a null backend for ActiveRecord. Unlike RSpec&#8217;s stub_object, rather than raise an exception on DB access, will NullDB DB interactions simply become no-ops. This is handy for things like testing after_save hooks in &#8230; <a href="http://devblog.avdi.org/2012/04/13/new-maintainer-needed-for-nulldb/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="https://github.com/nulldb/nulldb">NullDB</a>, for those who don&#8217;t know, is a null backend for ActiveRecord. Unlike RSpec&#8217;s stub_object, rather than raise an exception on DB access, will NullDB DB interactions simply become no-ops. This is handy for things like testing after_save hooks in isolation.</p>
<p>Myron Marston has done a stellar job shepherding it through the Rails 3 transition, but he&#8217;s busy with <a href="https://github.com/myronmarston/vcr">other awesome projects</a> now and has asked me to look for a new maintainer. So: If you&#8217;re interested in helping keep NullDB up to date with the latest changes to ActiveRecord, please get in touch!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/04/13/new-maintainer-needed-for-nulldb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing that a block is called</title>
		<link>http://devblog.avdi.org/2011/12/12/testing-that-a-block-is-called/</link>
		<comments>http://devblog.avdi.org/2011/12/12/testing-that-a-block-is-called/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 14:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1923</guid>
		<description><![CDATA[CapnKernul asks: Hey Avdi. How would you test that a method&#8217;s provided block is called in RSpec? Would you stub #to_proc (for &#38;block) and mock #call? Typically the way I test that a block is called goes something like this: &#8230; <a href="http://devblog.avdi.org/2011/12/12/testing-that-a-block-is-called/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://twitter.com/CapnKernul">CapnKernul</a> asks: </p>
<blockquote>
<p>Hey Avdi. How would you test that a method&#8217;s provided block is called<br />
in RSpec? Would you stub #to_proc (for &amp;block) and mock #call?
</p>
</blockquote>
<p> Typically the way I test that a block is called goes something like this: </p>
<pre class="src src-ruby">describe <span class="org-type">ZeroWing</span> <span class="org-keyword">do</span>
  let(<span class="org-constant">:probe</span>) { lambda{} }

  context <span class="org-string">"given a signal handler"</span> <span class="org-keyword">do</span>
    subject.on_we_get_signal(&amp;probe)

    it <span class="org-string">"triggers the handler when signaled"</span> <span class="org-keyword">do</span>
      probe.should_receive(<span class="org-constant">:call</span>)
      subject.we_get_signal!
    <span class="org-keyword">end</span>
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> That&#8217;s for the simple case of just checking if the block is called. When I want to make assertions about the block arguments, I often switch to a style which records the yielded arguments and then makes assertions on them after the fact. </p>
<pre class="src src-ruby">describe <span class="org-type">Array</span> <span class="org-keyword">do</span>
  subject { [1,2,3] }

  describe <span class="org-string">"#reverse_each"</span> <span class="org-keyword">do</span>
    it <span class="org-string">"yields the elements in backwards order"</span> <span class="org-keyword">do</span>
      yielded = []
      subject.reverse_each <span class="org-keyword">do</span> |e| yielded &lt;&lt; e <span class="org-keyword">end</span>
      yielded.should eq([3,2,1])
    <span class="org-keyword">end</span>
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> I don&#8217;t know if this is the best way, but it&#8217;s the way I usually do it. </p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/12/12/testing-that-a-block-is-called/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Making a Mockery of TDD</title>
		<link>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/</link>
		<comments>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 12:30:40 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[Behavior Driven Development]]></category>
		<category><![CDATA[Code smell]]></category>
		<category><![CDATA[law of demeter]]></category>
		<category><![CDATA[mock-objects]]></category>
		<category><![CDATA[stub objects]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test doubles]]></category>
		<category><![CDATA[Test-driven development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[Unit Tests]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1644</guid>
		<description><![CDATA[I made this gnomic remark on Twitter the other day: To be a successful mockist, you must dislike mocks. A lot of people re-tweeted it, so I guess I&#8217;m not completely alone in thinking this way. I should back up &#8230; <a href="http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I made this gnomic remark on Twitter the other day:</p>
<p><strong>To be a successful mockist, you must dislike mocks.</strong></p>
<p>A lot of people re-tweeted it, so I guess I&#8217;m not completely alone in thinking this way.</p>
<p>I should back up a bit. A &#8220;mock object&#8221;, or &#8220;mock&#8221;, is a specific kind of test double. It is an object used in a Unit Test which stands in for another object, and carries certain expectations about how what methods will be called, and how they will be called. If the expectations are not met, the test fails. By contrast, other test doubles, such as <em>stubs objects</em>, make no assertions about which methods will be called. This article is specifically about mock objects and mocked methods, which make an assertion about when, how many times, and with what arguments certain collaborator methods will be called.</p>
<p>The term &#8220;Mockist&#8221; refers to those programmers who use mock objects in their unit tests. There is another camp of programmers, called &#8220;Classicist&#8221; by Martin Fowler, who eschew mock objects entirely in their tests.</p>
<p>Actually, if you haven&#8217;t read <a href="http://martinfowler.com/articles/mocksArentStubs.html">Fowler&#8217;s article on the &#8220;mockist&#8221;/&#8221;classicist&#8221; divide</a>, go read it and then come back. There&#8217;s really no point in reading this post any further unless you have that as background. Fowler&#8217;s article is an excellent breakdown of the origin of the two camps, as well as a pretty objective evaluation of the pros and cons of both approaches to writing unit tests. Seriously, <a href="http://martinfowler.com/articles/mocksArentStubs.html">go read it right now</a>.</p>
<p>I&#8217;m a Mockist. I write tests that make assertions about object interactions, not just about static outcomes. I&#8217;ve been doing it for a while, and I&#8217;m pretty happy with the results.</p>
<p>However, it&#8217;s a technique that&#8217;s very easy misuse. Applied poorly, it can lead to testing suites which are so brittle they have to be either extensively rewritten or thrown out entirely when it comes time to change functionality or re-architect the code.</p>
<h3><strong>Mock Objects are a Test Smell</strong></h3>
<p>When I realize that I&#8217;m using a mock where I shouldn&#8217;t be, it&#8217;s often because I haven&#8217;t spent enough time on my test tooling, and as a result I don&#8217;t have a good way to make assertions about method output.</p>
<p>For instance, the other day I was building a Presenter for some Rails code. The presenter held references to both a domain model object (an ActiveRecord instance) and the Rails &#8220;template&#8221; object which makes various HTML-building methods available. The presenter&#8217;s job was to take model data and format it for display.</p>
<p>One of the first tests I wrote went something like this:</p>
<script src="https://gist.github.com/1195772.js?file=badmock.rb"></script><noscript><pre><code class="language-ruby ruby">it &quot;should generate a button&quot; do
  template.should_receive(:button_to).with(&quot;Vote&quot;).
    and_return(&quot;THE_HTML&quot;)
  subject.render_controls.should be == &quot;THE_HTML&quot;
end</code></pre></noscript>
<p>This test asserts that the presenter will call the button_to helper to generate some HTML.</p>
<p>I&#8217;ve been making an effort to write isolated tests which can be run without loading the full Rails infrastructure. This test completely isolates the presenter functionality from that of its collaborators. It doesn&#8217;t require any actual HTML to be generated, it just asserts that the presenter must use the button_to method and return the result.</p>
<p>The test felt <em>wrong </em>as soon as I wrote it. It was clearly brittle. I could look ahead and imagine, as the requirements for the HTML became more complex, how the mock object would have to grow more and more mock methods in order to keep up. The tests would become, in effect, an exact replica of the method implementation.</p>
<p>I decided to change up my spec setup a bit in order to pass in a template object which included the actual Rails tag helpers. Then I included the Capybara spec matchers for making assertions about HTML. In the end, the spec looked like this:</p>
<script src="https://gist.github.com/1195772.js?file=have_button.rb"></script><noscript><pre><code class="language-ruby ruby">it &quot;should render a vote button&quot; do
  subject.render_controls.should have_button('Vote')
end
</code></pre></noscript>
<p>The test is slightly less isolated now, but for a class which is all about generating strings, I think this style of test more suitable. Note that what I didn&#8217;t do was graduate the tests to the level of an integration or acceptance test. Instead, I added the minimum coupling necessary to get rid of the suspect mock object.</p>
<p>In my experience, well-isolated tests lead to neatly decoupled code. Not to mention that they run really fast. Rather than tie my presenter tests to the entire Rails stack, I let the mock object pain guide me to the one area where a little relaxation in my isolation discipline would lead to a big gain in productivity.</p>
<h3>Mock Objects are a Code Smell</h3>
<p>In the preceding case, the mock object was a test smell. But mock objects are more often smelly because they are telling you something about the system under test.</p>
<p>A <a href="http://c2.com/xp/CodeSmell.html">Code Smell</a> is defined as &#8220;<em>a hint that something has gone wrong somewhere in your code&#8221;</em>. A hint, not a certainty. Whenever I use a mock object to assert that a certain method call must be made, a little voice in my head says &#8220;should I really be using a mock object here?&#8221;. When a test has more than one or two mocked method calls, that little voice gets a lot bigger.</p>
<p>In my experience, multiple mocked methods often indicate that either a) the method being tested is trying to do too much; or b) the method being tested has high structural coupling. As I wrote in <a href="http://avdi.org/devblog/2011/04/07/rspec-is-for-the-literate/">another testing article</a>, mocks are like the hydrogen peroxide of programming. They &#8220;fizz up&#8221; when they encounter highly-coupled code. Show me a test with a lot of mocked method calls, and I&#8217;ll show you a class under test which violates the <a href="http://avdi.org/devblog/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/">law of Demeter</a>. And which is, consequently, a liability to future code changes.</p>
<p>Mocks act as a canary in coal mine: they are an early warning system that your code is beginning to depart from the path of small methods, each having a single responsibility, and each interacting with a very small set of collaborators.</p>
<h3>Mock objects are for Design</h3>
<p>Which brings me to my next point about using mock objects: mock objects are all about design. They were developed hand-in-hand with the &#8220;Behavior Driven Development&#8221; movement, which sought to re-emphasise the design component of TDD. Here are the inventors of mock objects, talking about them in the intro to an <a href="http://static.mockobjects.com/files/mockrolesnotobjects.pdf">OOPSLA 2004 paper on using mocks</a>:</p>
<blockquote><p>Mock Objects is an extension to Test-Driven Development that supports good Object-Oriented design by guiding the discovery of a coherent system of types within a code base. It turns out to be less interesting as a technique for isolating tests from third-party libraries than is widely thought.</p></blockquote>
<p>Guiding design isn&#8217;t just a side-benefit of using mocks; it&#8217;s the <em>primary reason to use them</em>.</p>
<p>Which means that if you aren&#8217;t using tests to drive your design, there&#8217;s little point to using mock objects.  I suspect this is the root of a lot of the the arguments over whether to use mocks or not; if your primary reason for writing unit tests is verification and avoiding regressions, mock objects aren&#8217;t going to buy you much. And people talking about how useful they are aren&#8217;t going to make a lot of sense.</p>
<p>Mock objects also make more sense in an <em>outside-in</em> model of test-driven development. They enable developers to ferret out the needed interfaces of objects that don&#8217;t exist yet. Many if not most of the mocks I write are mocks of classes and methods I have yet to write. The mocks I write while TDDing one layer of the design gives me the clues I need to work out the necessary responsibilities of the next layer down.</p>
<p>(By the way, that OOPSLA paper is full of good advice on how to use mock objects without shooting yourself in the foot. <a href="http://static.mockobjects.com/files/mockrolesnotobjects.pdf">The whole thing</a> is worth reading)</p>
<h3>Mock objects are for Commands</h3>
<p>This is a distinction that is just starting to become clear to me. You may be familiar with notion of  &#8221;<a href="http://martinfowler.com/bliki/CommandQuerySeparation.html">command/query separation</a>&#8220;. This is when you make an effort to divide all methods into either <em>command</em> or <em>query</em> methods. Command methods cause something to change, either internally or externally to the receiver, and return no value. Conversely, query methods change nothing, (i.e. they have no side-effects), and are used solely for their return values.</p>
<p>As a general rule, I think mock objects are mainly useful when describing command methods. Their use is suspect for testing query methods. As a corollary to this observation, mocked methods with defined return values are often (though not always) a warning sign. I find most of my test doubles fall into one of two categories: stubs with no behavior, just a return value; and mocks that expect a certain method call, but define no return value (no &#8216;and_return()&#8217;, in RSpec terms).</p>
<p>This distinction has the side effect of encouraging you, as a user of mock objects, towards a design that has a strong delineation between queries and commands. This is widely regarded in OO circles as a Good Thing.</p>
<p><span style="font-size: 15px; font-weight: bold;">Conclusion</span></p>
<p>This has been a brain dump of some of my current thinking on mock objects. As such, it&#8217;s probably not as clear or well organized as it could be. To sum up: mock objects are helpful, but they are as often useful for drawing attention to problematic tests and code as they are for specifying object interactions. Mock objects are only a meaningful exercise when tests are being used to drive design. And finally, mock objects tend to make the most sense when specifying pure command methods.</p>
<p>I hope you find some of these observations helpful in your own TDD practice.</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" style="border: none; float: right;" src="http://img.zemanta.com/zemified_e.png?x-id=9b52b287-2e6f-4f38-8e81-bb7d24014416" alt="Enhanced by Zemanta" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Software Superstitions</title>
		<link>http://devblog.avdi.org/2011/08/08/software-superstitions/</link>
		<comments>http://devblog.avdi.org/2011/08/08/software-superstitions/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 13:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[Folklore]]></category>
		<category><![CDATA[Superstition]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1508</guid>
		<description><![CDATA[If we are not honest about the causes of a bad situation, we pose a significant danger to those who are either less-experienced or uncertain about their own situation. Take a slow test suite, for example. Having a test suite &#8230; <a href="http://devblog.avdi.org/2011/08/08/software-superstitions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<blockquote><p>If we are not honest about the causes of a bad situation, we pose a significant danger to those who are either less-experienced or uncertain about their own situation. Take a slow test suite, for example. Having a test suite that actively hinders a developer from running portions of it while developing is a deterent even to run the suite at all. As the run time climbs into minutes, the test suite becomes an antagonist, rather than the helper and guide that it should be. Instead of rationalizing, say you have some serious design flaws in your system. Or, say you have a large codebase and a huge team consisting of people with varying desires to write automated tests. When we mask the real causes of a problem, it has the potential to confuse less-experienced developers who look to us for guidance. For example, thinking a slow test suite is inevitable could stop someone from asking for help optimizing their own codebase while there is still time.</p>
<p>via <a href="http://programmingtour.blogspot.com/2011/08/rationalizing-real-world.html">On Being A Journeyman Software Developer: Being honest vs Making excuses</a>.</p></blockquote>
<p>I completely agree with Corey here. There are very few true cases of &#8220;that&#8217;s just the way it is&#8221;. You just <em>can&#8217;t</em> do continuous deployment&#8230; except that you can. You <em>can&#8217;t </em>have a productive distributed team&#8230; except that so many companies do. You can&#8217;t <em>really </em>isolate your units in order to test them&#8230; unless you have the discipline to do just that.</p>
<p>&#8220;You can&#8217;t speed up a project by adding programmers&#8221;. That&#8217;s about the only rule of software development that I can think of which has stayed largely inviolate. And even that one is somewhat fungible depending on the type of project and the culture that is in place. Most &#8220;rules&#8221; are really cultural mores, taboos, and superstitions, passed from team member to team member.</p>
<p>What superstitions have you internalized?</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" style="border: none; float: right;" src="http://img.zemanta.com/zemified_e.png?x-id=474267fd-0e3b-4f52-a37f-a069e43dd2d3" alt="Enhanced by Zemanta" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/08/08/software-superstitions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Demeter: It&#8217;s not just a good idea. It&#8217;s the law.</title>
		<link>http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/</link>
		<comments>http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 13:30:20 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[coupling]]></category>
		<category><![CDATA[demeter]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[law of demeter]]></category>
		<category><![CDATA[objects]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[structural coupling]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1357</guid>
		<description><![CDATA[Is #try really so bad? In response to my recent post about #try being a code smell, a lot of people made the reasonable objection that the example I used&#8212;of using #try on a a Hash&#8212;was a pathological case. A &#8230; <a href="http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Is <code>#try</code> really so bad?</h3>
<p>In response to my recent <a href="http://avdi.org/devblog/2011/06/28/do-or-do-not-there-is-no-try/">post about <code>#try</code> being a code smell</a>, a lot of people made the reasonable objection that the example I used&#8212;of using <code>#try</code> on a a Hash&#8212;was a pathological case. A much more typical usage of <code>#try</code> looks like this:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Dept: #{user.department.try(:name)}"
end
</pre>
<p><code>user</code> may or may not have an associated department, so the call to <code>Department#name</code> is wrapped in a <code>#try</code>. If there is an associated department, its name will be returned. If not, the result will be <code>nil</code>.</p>
<p>Straightforward enough. Is there anything wrong with this code?</p>
<p>I can think of a a few things. For one thing, it&#8217;s ugly. For my money, one of the hallmarks of beautiful code is that it&#8217;s visually consistent: similar operations have similar appearance. In the code above, we access one attribute with simple dot syntax (<code>.name</code>), and another with a very different-looking <code>.try(:name)</code>, even though in both cases the concept we are trying to express is the same: &#8220;get the &#8216;name&#8217; attribute&#8221;.</p>
<p>It&#8217;s a variety of ugliness that tends to proliferate, too. Starting with the code above, it&#8217;s not a very big leap to get to this:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Boss: #{user.department.try(:head).try(:name)}"
end
</pre>
<p>Yuck.</p>
<p>And then there are the tests. They&#8217;ll probably look something like this:</p>
<pre name="code" class="ruby">
describe '#user_info' do
  subject { user_info(user) }
  let(:user) { stub('user', :name => "Bob", :department => stub(:name => "Accounting")) }
  specify {
    subject.should match(/Dept: Accounting/)
  }
end
</pre>
<h3>Metastasizing mocks</h3>
<p>This, again, doesn&#8217;t seem so bad. But give that test suite six months of active development, and chances are the tests wind up looking more like this:</p>
<pre name="code" class="ruby">
describe '#user_info' do
  subject { user_info(user) }
  let(:user) { 
    stub('user', 
         :name => "Bob", 
         :department => 
           stub(:name     => "Accounting",
                :head     => 
                  stub(:name     => "Jack", 
                       :position => stub(:title => "Vice President"))),
            :division => stub(:name => "Microwave Oven Programming")),
          :position => stub(:title => "Senior Bean Counter"))
 }
  # examples...
end
</pre>
<p>Not only that, the same tree of stubs will probably be duplicated, with subtle differences, for every test group that interacts with a User&#8212;because no one has time to sort out the specific subset of stubs that a given test actually <em>needs</em> in order to function.</p>
<p>At some point the client will decide that users really need to be associated with zero or more departments instead of just one. At that point some unlucky programmer will spend a late night fixing the 300 tests this &#8220;small change&#8221; breaks because of all the stubs that model the old behavior. Then the next day he&#8217;ll write an angry rant about how mock objects are a bad idea.</p>
<h3>Structural coupling</h3>
<p>The seed of this all-too-common predicament is <em>structural coupling</em>. What&#8217;s structural coupling? To define it, let&#8217;s start with a review of the DRY principle:</p>
<blockquote><p>Every piece of knowledge must have a single, unambiguous, authoritative representation within the system.</p></blockquote>
<p>It&#8217;s easy to think about DRYness just in terms of data: e.g., there should be only one place in the system for API keys; they shouldn&#8217;t just be copy-and-pasted willy-nilly throughout the codebase. But DRY applies equally to <em>structural knowledge</em>: knowledge about the composition of and relationships between your objects.</p>
<p>Let&#8217;s take a look at the code we started out with:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Dept: #{user.department.try(:name)}"
end
</pre>
<p>This seemingly innocuous code makes the following assumptions:</p>
<ul>
<li><code>user</code> will have a name property.</li>
<li><code>user</code> may or may not have a single department.</li>
<li><code>user</code>&#8216;s department, in turn, has a name property</li>
</ul>
<p>By going two levels deep into <code>user</code>&#8216;s associations, we&#8217;ve made a <em>structural coupling</em> between this code and the models it works with. We&#8217;ve duplicated knowledge about a User&#8217;s associations&#8212;canonically located in the User and Department classes&#8212;in the <code>#user_info</code> method.</p>
<p>And the <code>#try</code> method was an enabler. By papering over the ugly <code>user.department &#038;&#038; user.department.name</code> construct we&#8217;d otherwise have had to use, <code>#try</code> made the coupling an easier syntactical pill to swallow.</p>
<p>This would be bad enough if we made a habit of it, because we&#8217;d have to change every method with a similar structural coupling whenever the innards of User or Department changed. But because we&#8217;re good Test-Driven developers, we then proceeded to couple <em>dozens</em> of test suites to a specific model structure, in the form of stubs and mock objects.</p>
<p>This is clearly an undesirable outcome. Wouldn&#8217;t it be handy to have a simple rule that helps us avoid structural coupling?</p>
<h3>The Law of Demeter</h3>
<p>Back in the 1980s, a group of programmers working on a project called the Demeter system realized that certain qualities in their object-oriented code led to the code being easier to maintain and change. Qualities such as low coupling; information hiding; localization of information, and narrow interfaces between objects. They asked themselves: &#8220;Is there a <em>simple</em> heuristic that humans <em>or</em> machines can apply to code to determine whether it has these positive qualities?&#8221;.</p>
<p>The answer they came up with came to be known as the &#8220;Law of Demeter&#8221;. It is stated as follows:</p>
<blockquote><p>
For all classes C. and for all methods M attached to C, all objects to which M sends a message must be instances of classes associated with the following classes:</p>
<ol>
<li>The argument classes of M (including C).</li>
<li>The instance variable classes of C.</li>
</ol>
<p>(Objects created by M, or by functions or methods which M calls, and objects in global variables are considered as arguments of M.)
</p></blockquote>
<p><a href="http://c2.com/cgi/wiki?LawOfDemeter">WikiWiki explains the law</a> like this:</p>
<ul>
<li>Your method can call other methods in its class directly.</li>
<li>Your method can call methods on its own fields directly (but not on the fields&#8217; fields).</li>
<li>When your method takes parameters, your method can call methods on those parameters directly.</li>
<li>When your method creates local objects, that method can call methods on the local objects.</li>
</ul>
<p>If that still seems confusing, here&#8217;s an alternative explanation from Peter Van Rooijen:</p>
<ul>
<li> You can play with yourself.</li>
<li> You can play with your own toys (but you can&#8217;t take them apart),</li>
<li> You can play with toys that were given to you.</li>
<li> And you can play with toys you&#8217;ve made yourself.</li>
</ul>
<p>The Demeter programmers wrote up their experiences in a paper called <a href="http://www.ccs.neu.edu/research/demeter/papers/law-of-demeter/oopsla88-law-of-demeter.pdf"><cite>Object-Oriented Programming: An Objective Sense of Style</cite></a>. What they found was that when methods were written in a form which complied with the Law of Demeter, the resulting codebase was easier to maintain and evolve.</p>
<p>It&#8217;s important to understand that the Law of Demeter is a <em>heuristic</em>, not an end in and of itself. It is not a law in the sense that you &#8220;must&#8221; write your code in a certain way. Rather, it is a law in the sense that it has been consistently observed that if code complies with the Law of Demeter, it almost certainly has a number of the qualities&#8212;encapsulation, loose coupling, etc.&#8212;desirable in an OO system.</p>
<h3>Laying down the law</h3>
<p>With that in mind, let&#8217;s take one more look at our example code:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Dept: #{user.department.try(:name)}"
end
</pre>
<p>This code does not comply with the Law of Demeter. In addition to calling methods on its parameter, <code>user</code>, it also calls a method on the <em>result</em> of one of those methods: (<code>department.name</code>).</p>
<p>Assuming this is a Rails program, it is extremely easy to change the code to satisfy the law. First, we make a one-line addition to the User class:</p>
<pre name="code" class="ruby">
class User
  delegate :name, :to => :department, :prefix => true, :allow_nil => true
  # ...
end
</pre>
<p>The <a href="http://api.rubyonrails.org/classes/Module.html#method-i-delegate"><code>#delegate</code></a> macro, provided by ActiveSupport, generates a new method <code>User#department_name</code> which delegates to the user&#8217;s <code>#department</code>. By supplying <code>:allow_nil => true</code>, we ensure that the method will simply return nil in the case when there is no department associated with the user.</p>
<p>Here&#8217;s our code again, updated to use the new method:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Dept: #{user.department_name}"
end
</pre>
<p>The code now respects the Law of Demeter: it is coupled only to the immediate interface of the <code>user</code> parameter.</p>
<p>The updated test suite now has only one stub object:</p>
<pre name="code" class="ruby">
describe '#user_info' do
  subject { user_info(user) }
  let(:user) { stub('user', :name => "Bob", :department_name => "Accounting") }
  specify {
    subject.should match(/Dept: Accounting/)
  }
end
</pre>
<p>Already we have a simpler test suite. But the real benefit comes when it is time to change the models. Let&#8217;s consider the case when a User changes from being linked to just one department, to having a list of zero or more departments. How we re-implement <code>User#department_name</code> depends on the needs of the domain. Let&#8217;s say the department name should now be a comma-separated list:</p>
<pre name="code" class="ruby">
class User
  def department_name
    departments.join(", ")
  end
end
</pre>
<p>We replace our delegate method with a method implementing the new semantics. And that&#8217;s the only change! The <code>#user_info</code> method remains the same, as does every test suite that references <code>User#departmentname</code>.</p>
<p>By adhering to the Law of Demeter, we have decreased coupling, and increased the velocity with which we can make changes to the business logic.</p>
<h3>Objection #1: What about method chains?</h3>
<p>&#8220;But Avdi&#8221; you may object, &#8220;it sounds like a good guideline, but clearly it&#8217;s not something to be rigidly adhered to in Ruby code. If we followed it all the time we could never do method chaining!&#8221;</p>
<p>Method chains are a core Ruby idiom, to be sure. As an example, here&#8217;s a method which takes a string and generates a &#8220;slug&#8221; for use as an identifier or as a a URL component:</p>
<pre name="code" class="ruby">
def slug(string)
  string.strip.downcase.tr_s('^[a-z0-9]', '-')
end
</pre>
<p>That&#8217;s one, two, three levels of method call. That can&#8217;t comply with the Law of Demeter, but it surely is concise and convenient!</p>
<p>Look again at the definition of the Law: it never says anything about the number of methods called, or the number of objects a method uses. It is strictly concerned with the number of <em>types</em> a method deals with.</p>
<p>The <code>#slug</code> method expects a String, and calls three methods, each one returning&#8230; another String. In fact, because it only calls methods for the type of object (String) passed into it as parameters, we find that this method complies perfectly with the Law of Demeter.</p>
<p>Likewise with another common Ruby pattern, chains of Enumerable methods like <code>#map</code> and <code>#select</code>. Because each returns another Enumerable object, there is no violation.</p>
<h3>Objection #2: Delegation explosion</h3>
<p>Another objection to Demeter is that strictly following it results in objects which are full of attributes which aren&#8217;t a direct part of their responsibility. Quoting Mark Wilden in the comments on my previous article:</p>
<blockquote><p>
Why should a Human have to know whether a Country has a name? Or any other attribute (unless it needs them itself)? If a Human is associated with multiple Countries (birth, residence, voting, vacation, etc.) does it then have to duplicate this delegation for each method of each country?</p>
<p>What about attributes that clearly have nothing to do with Human? Yes, one might say that a Human has a country_name. But does a Human have a country_population? A country_mortality_rate? I would say it does not, but Demeter insists that it must.
</p></blockquote>
<p>In the Object-Oriented view of the world, objects are not merely bags of attributes. They are entities to which you send messages and from which you receive replies. The classic example is a financial transaction: if I am a shopkeeper and you buy something from me, I don&#8217;t ask you for your wallet, rummage around until I find a credit card, and then copy down the information I need. Instead, I ask you for your credit card number and expiration date.</p>
<p>Putting this in object terms, a payment system which calls <code>person.wallet.credit_cards.first.number</code> exhibits tight structural coupling, and is closer in spirit to the data-structure-oriented programming which preceded OO. From an objects-sending-messages standpoint, it is perfectly reasonable for a Person to have a creditcard_number.</p>
<p>An important and often neglected point to hit on, before we move on: in an Object-Oriented system, it is prfectly allowable (and even encouraged) for objects to have <em>personas</em> or <em>facets</em>. A doctor deals with a patient&#8217;s physical symptoms while the reception desk deals with her wallet and insurance info. You wouldn&#8217;t walk into a doctor&#8217;s office, step up to the receptionist, and take off your shirt (unless you were on very good terms with the receptionist!).</p>
<p>Likewise, an object can have a large API, but only expose subsets of that API to different collaborators. Some languages enforce these subset relationships quite strictly; e.g. C++ with its private inheritance, and interfaces in Java. In other languages, such as Ruby, the restriction may be more about convention than something the language enforces. There&#8217;s nothing wrong with having a large API, so long as individual collaborators only talk to well-defined subsets of it.</p>
<p>But what about Mark&#8217;s example <code>human.country_mortality_rate</code>? Surely that&#8217;s pushing it a bit far?</p>
<p>Perhaps it is. But Demeter doesn&#8217;t prevent us from interacting with an objects second- and third-order associations; it simply asserts that we can&#8217;t interact with all of those objects <em>in the same method</em>. Look again at the formulation of the law:<br />
<blockquote>&#8230;all objects to which M sends a message&#8230;</p></blockquote>
<p> Demeter is a rule about methods <em>only</em>; it does not limit the set of types a <em>class</em> can interact with.</p>
<p>So this is perfectly legal:</p>
<pre name="code" class="ruby">
class StatPresenter
  def human_stats(human)
    "Age: #{human.age}.nCountry stats:n#{country_stats(human.country)}"
  end

  def country_stats(country)
    "  Mortality rate: #{country.mortality_rate}"
  end
end
</pre>
<p>Of course, you could completely violate the <em>spirit</em> of Demeter by taking this too far; something the authors of the Demeter paper note. Realistically, we&#8217;d probably want to break that <code>StatPresenter</code> class up into smaller classes once it started interacting with many different types of object.</p>
<p>The important thing, from the standpoint of Demeter, is to avoid tying a <em>single method</em> to a deep hierarchy of types, as well as limiting the <em>number</em> of types one method deals with.</p>
<p>One of the most basic ways we can limit the number of types a given method must be aware of is to eliminate the common case of &#8220;maybe nil&#8221; parameters. Remember, <code>NilClass</code> is a type too, and when a parameter might be nil we&#8217;ve increased the number of types the method has to know about by one. </p>
<p>As an example, the following version of the code above, while technically Demeter-compliant, is once again riddled with <code>#try</code> calls:</p>
<pre name="code" class="ruby">
class StatPresenter
  def human_stats(human)
    "Age: #{human.age}.nCountry stats:n#{country_stats(human.country)}"
  end

  def country_stats(country) # country may be nil
    "  Population: #{country.try(:population)}n" +
    "  Mortality rate: #{country.try(:mortality_rate)}n"
  end
end
</pre>
<p>The set of types <code>#country_stats</code> deals directly with is: <code>StatPresenter</code> (self), <code>Country</code>, and <code>NilClass</code>.</p>
<p>We can&#8217;t always get rid of switching on <code>nil</code> entirely, but what Demeter-influenced code gives us the opportunity to do is to easily confine that switch to a single location. Let&#8217;s rewrite the code above:</p>
<pre name="code" class="ruby">
class StatPresenter
  def human_stats(human)
    "Age: #{human.age}." + (human.country ? 
      "nCountry stats:n#{country_stats(human.country)}" :
      "n(No Country Stats)")
  end

  def country_stats(country)
    "  Population: #{country.population}n" +
    "  Mortality rate: #{country.mortality_rate)n"
  end
end
</pre>
<p>With this final edit, we&#8217;ve reduced the coupling of each method to a minimal point. <code>StatPresenter#human_stats</code> deals only with <code>Human</code> objects, and all it knows about <code>#country</code> is that it may or may not be there. <code>StatPresenter#human_stats</code> only knows about <code>Country</code> objects.</p>
<h3>Bringing Demeter to work</h3>
<p>&#8220;OK, fine. I can see that the Law of Demeter is a great guideline, at least in theory. But who has time to do all that refactoring? I have deadlines to meet!&#8221;</p>
<p>While refactoring code to comply with Demeter can certainly improve its design, I don&#8217;t think Demeter becomes truly practical until you incorporate it consistently into your coding style. Like many low-level &#8220;code construction&#8221; techniques&#8212;such as good variable naming&#8212;its value lies less in coming in and applying it after the fact, and more in practicing it until it becomes second nature.</p>
<p>Let&#8217;s take a look at how we&#8217;d add the department name to the <code>#user_info</code> method using TDD and the Law of Demeter. Here&#8217;s the code before adding the new functionality:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}"
end
</pre>
<p>Now let&#8217;s add the department name.</p>
<ol>
<li>
<p>We write our test first:</p>
<pre name="code" class="ruby">
describe '#user_info' do
  subject { user_info(user) }
  let(:user) { stub('user', :name => "Bob", :department_name => "Accounting") }
  specify {
    subject.should match(/Dept: Accounting/)
  }
end
</pre>
<p>We know that nested mock/stub objects is a smell indicating structural coupling, so we force ourselves to write a  stub for the <code>user</code> object we <em>wish</em> we had. The <code>User#department_name</code> method doesn&#8217;t exist yet; we make a mental note to implement it. If we forget, the omission will be caught by our acceptance and/or integration tests.</p>
</li>
<li>We run the spec. It fails, because we haven&#8217;t implemented it yet</li>
<li>
<p> We write enough code to make the test pass:</p>
<pre name="code" class="ruby">
def user_info(user)
  "Name: #{user.name}. Dept: #{user.department_name}"
end
</pre>
</li>
<li>We run the tests again, and this time they pass.</li>
<li>
<p>The final step is to implement the <code>User#department_name</code> method. We could write a test asserting that the method delegates to <code>Department</code>; personally, I find this a little redundant and would just write the delegation and call it done:</p>
<pre name="code" class="ruby">
class User
  delegate :name, :to => :department, :prefix => true, :allow_nil => true
  # ...
end
</pre>
</li>
</ol>
<p>Revisiting your code to make it Demeter-compliant after the fact will indeed slow you down. By incorporating the rule into your habits, to the point that it becomes second nature, you reduce the impact (if any) to the point where it becomes insignificant. This is especially true in Ruby and Rails, where techniques such as composition-and-delegation, viewed as &#8220;heavyweight patterns&#8221; in some languages, become one-liners. And any fractional slowdown you <em>do</em> experience from an extra test run here and there will be more than made up for by the ease of changing your loosely-coupled code as requirements change. With discipline and practice, it is possible to be both <a href="http://avdi.org/devblog/2011/01/07/fast-and-good/">fast and good</a>.</p>
<h3>Conclusion</h3>
<p>To summarize:</p>
<ul>
<li><code>#try</code> is more often than not indicative of structural coupling. Structural coupling, in turn, violates the DRY principle.</li>
<li>Structural coupling, left unchecked, can substantially slow the evolution of a project.</li>
<li>The Law of Demeter, which sets limits on the number of types a single method can interact with, is a heuristic for identifying code that (among other positive properties) has low structural coupling.</li>
<li>When refactor our code to comply with the Law of Demeter, it tends to reduce structural coupling both in application code and in tests. As a side effect, it tends to eliminate the need for <code>#try</code> calls and similar constructs.</li>
<li>Contrary to popular belief, Demeter does not limit the number of of dots in a method call chain. It also doesn&#8217;t limit the number of classes a class can interact with.</li>
<li>The best way to incorporate Demeter into your work is to make it a habit, rather than a cleanup chore.</li>
</ul>
<p>Do you look for Demeter violations in your code? Do you think there are still some instances where a <code>#try</code> makes sense? Do you have more questions about the Law of Demeter or structural coupling? As always, I welcome feedback in the comments!</p>
<p><i>P.S. It&#8217;s my birthday! To celebrate, for 24 hours I&#8217;m offering <strong>50%</strong> off on my book, <a href="http://exceptionalruby.com?utm_campaign=catchthrow"><cite>Exceptional Ruby</cite></a>. Use code <code>HAPPY0X1F</code> to get the discount.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/feed/</wfw:commentRss>
		<slash:comments>72</slash:comments>
		</item>
		<item>
		<title>Linkdump #8</title>
		<link>http://devblog.avdi.org/2011/04/15/linkdump-8/</link>
		<comments>http://devblog.avdi.org/2011/04/15/linkdump-8/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 21:58:50 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[llvm]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[spdy]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[tcp]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test-unit]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[yield]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1204</guid>
		<description><![CDATA[Scriptensity: Emscripten 1.0! This is the first I&#8217;ve heard of this project: it&#8217;s an LLVM-to-Javascript compiler. Which means you can (for instance) compile C++ to Javascript. I can&#8217;t decide if this is amazing or just batshit insane. Probably both. tags: &#8230; <a href="http://devblog.avdi.org/2011/04/15/linkdump-8/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<ul class="diigo-linkroll">
<li>
<p class="diigo-link"><a href="http://syntensity.blogspot.com/2011/04/emscripten-10.html">Scriptensity: Emscripten 1.0!</a></p>
<p class="diigo-description">This is the first I&#8217;ve heard of this project: it&#8217;s an LLVM-to-Javascript compiler. Which means you can (for instance) compile C++ to Javascript. I can&#8217;t decide if this is amazing or just batshit insane. Probably both.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/javascript">javascript</a>             <a href="http://www.diigo.com/user/avdigrimm/llvm">llvm</a>             <a href="http://www.diigo.com/user/avdigrimm/web">web</a>             <a href="http://www.diigo.com/user/avdigrimm/c++">c++</a>             <a href="http://www.diigo.com/user/avdigrimm/c">c</a>             <a href="http://www.diigo.com/user/avdigrimm/compilers">compilers</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Overall Emscripten is now in very good shape. It can probably compile most any C/C++ project out there, subject to some limitations (like JS not allowing C-style multithreading).</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="https://github.com/citrusbyte/contest">citrusbyte/contest &#8211; GitHub</a></p>
<p class="diigo-description">Another contexts plugin for Test::Unit.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/tdd">tdd</a>             <a href="http://www.diigo.com/user/avdigrimm/testing">testing</a>             <a href="http://www.diigo.com/user/avdigrimm/test-unit">test-unit</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://carboni.ca/blog/p/To-Yield-or-Not-to-Yield-An-Inferable-Question">To Yield or Not to Yield: An Inferable Question | Blog | Carbonica</a></p>
<p class="diigo-description">A terrific article on statically analyzing Ruby code to infer whether a given method will yield to a block.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://www.igvita.com/2011/04/07/life-beyond-http-11-googles-spdy">Life beyond HTTP 1.1: Google&rsquo;s SPDY &#8211; igvita.com</a></p>
<p class="diigo-description">I knew about SPDY. But I didn&#8217;t realize Google was already using it in production.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/http">http</a>             <a href="http://www.diigo.com/user/avdigrimm/tcp">tcp</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Turns out, while the original work and tests around SPDY were done in the Chromium project, since then, the official Google Chrome client has shipped with built-in SPDY support, and not surprisingly, Google&#8217;s servers are also SPDY enabled. In other words, if you use Chrome, and you&#8217;re using Google services, then many of those pages are not arriving to you over HTTP &#8211; <a rel="nofollow" href="http://groups.google.com/group/spdy-dev/msg/dcc9c3a3e50c694f">you are actually running over SPDY</a>!</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="https://spreadsheets0.google.com/pub?hl=en&amp;hl=en&amp;key=0AiZsKd8d4hSJdHFFbjR5aWNjWjlzWlhiNGxQejdBWWc&amp;output=html">Ruby HTTP clients features</a></p>
<p class="diigo-description">A spreadsheet comparing Ruby HTTP libraries.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/http">http</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://www.reddit.com/r/compsci/comments/gprp0/is_there_a_list_of_the_canonical_introductory/c1pcqe5?context=3">List of the canonical introductory textbooks covering the major branches of computer science</a></p>
<p class="diigo-description">Handy list.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/computer">computer</a>             <a href="http://www.diigo.com/user/avdigrimm/science">science</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/books">books</a></p>
</li>
</ul>
<p class="diigo-ps">Posted from <a href="http://www.diigo.com">Diigo</a>. The rest of my favorite links are <a href="http://www.diigo.com/user/avdigrimm">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/04/15/linkdump-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linkdump #7</title>
		<link>http://devblog.avdi.org/2011/04/10/linkdump-7/</link>
		<comments>http://devblog.avdi.org/2011/04/10/linkdump-7/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 15:21:35 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[literate programming]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1191</guid>
		<description><![CDATA[Hacker Chat: Pinboard Creator Maciej Ceglowski Talks About Why Boring Architecture is Good, and More Wise words. tags: development I think many developers (myself included) are easily seduced by new technology and are willing to burn a lot of time &#8230; <a href="http://devblog.avdi.org/2011/04/10/linkdump-7/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<ul class="diigo-linkroll">
<li>
<p class="diigo-link"><a href="http://www.readwriteweb.com/hack/2011/02/pinboard-creator-maciej-ceglow.php">Hacker Chat: Pinboard Creator Maciej Ceglowski Talks About Why Boring Architecture is Good, and More</a></p>
<p class="diigo-description">Wise words.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">I think many developers (myself included) are easily seduced by new technology and are willing to burn a lot of time rigging it together just for the joy of tinkering.  So nowadays we see a lot of fairly uninteresting web apps with very technically sweet implementations.   In designing Pinboard, I tried to steer clear of this temptation by picking very familiar, vanilla tools wherever possible so I would have no excuse for architectural wank.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://www.heartmindcode.com/blog/2011/04/creating-ruby-hashes">Creating Ruby Hashes | Heart, Mind and Code</a></p>
<p class="diigo-description">Detailed coverage of Ruby features, just the sort of thing I love :-)</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">I just created a quick Ruby screencast on creating hashes. I don&rsquo;t cover all of the possibilities, but I do show 5 ways&mdash;including one you should never use.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://www.readwriteweb.com/hack/2011/04/6-free-e-books-on-nodejs.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+readwriteweb+%28ReadWriteWeb%29">6 Free E-Books and Tutorials for Learning and Mastering Node.js</a></p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/javascript">javascript</a>             <a href="http://www.diigo.com/user/avdigrimm/nodejs">nodejs</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://marxsoftware.blogspot.com/2011/03/jdk-7-new-interfaces-classes-enums-and.html">JDK 7: New Interfaces, Classes, Enums, and Methods</a></p>
<p class="diigo-description">A rundown of some of the lesser-known additions to Java 7.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/java">java</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">There are numerous new classes, enums, methods, and interfaces being added to <a rel="nofollow" href="http://jdk7.java.net/">JDK 7</a> that may not get significant coverage in the blogs and articles on Java 7</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files">Logs Are Streams, Not Files</a></p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/rails">rails</a>             <a href="http://www.diigo.com/user/avdigrimm/logging">logging</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Unfortunately, Rails stands out as a major exception to this simple principle. It creates its own log directory and writes various files into it; some plugins even take it upon themselves to write their own, separate logfiles. This hurts the local development experience: what you see in your terminal isn&rsquo;t complete, so you have to open a separate window with <code>tail -f log/*.log</code> to get the information you want. But it hurts the deployment experience even more, because you end up having to tinker around with a bunch of Rails logger configuration options to get your logs from all your web machines to merge into a single stream.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://www.loggly.com">Loggly&nbsp;|&nbsp;Logging as a Service</a></p>
<p class="diigo-description">Cloud-based logging service.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/logging">logging</a>             <a href="http://www.diigo.com/user/avdigrimm/monitoring">monitoring</a></p>
</li>
<li>
<p class="diigo-link"><a href="https://papertrailapp.com">Papertrail &#8211; hosted log management. Aggregate, tail, search &#8211; instantly.</a></p>
<p class="diigo-description">A different cloud-based logging service</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/logging">logging</a>             <a href="http://www.diigo.com/user/avdigrimm/monitoring">monitoring</a></p>
</li>
<li>
<p class="diigo-link"><a href="https://github.com/ddollar/rails_log_stdout">ddollar/rails_log_stdout &#8211; GitHub</a></p>
<p class="diigo-description">Configure a Rails 2 or 3 app to log to STDOUT by default</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/rails">rails</a>             <a href="http://www.diigo.com/user/avdigrimm/logging">logging</a></p>
</li>
<li>
<p class="diigo-link"><a href="https://github.com/facebook/scribe/wiki">Scribe &#8211; GitHub</a></p>
<p class="diigo-description">Interesting distributed logging project.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/logging">logging</a>             <a href="http://www.diigo.com/user/avdigrimm/monitoring">monitoring</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://christophercliff.github.com/sausage">sausage.js</a></p>
<p class="diigo-description">A jQuery plugin foor pagination.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/jquery">jquery</a>             <a href="http://www.diigo.com/user/avdigrimm/pagination">pagination</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/javascript">javascript</a>             <a href="http://www.diigo.com/user/avdigrimm/ui">ui</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Sausage is a jQuery UI widget for contextual pagination. It complements long or infinite-scrolling pages by keeping the user informed of her location within the document</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/remote.pdf">Cloud Haskell</a></p>
<p class="diigo-description">(PDF) A Haskell DSL for Erlang-style distributed computing.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/haskell">haskell</a>             <a href="http://www.diigo.com/user/avdigrimm/erlang">erlang</a>             <a href="http://www.diigo.com/user/avdigrimm/distributed">distributed</a>             <a href="http://www.diigo.com/user/avdigrimm/csp">csp</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://timelessrepo.com/literate-programming.html">literate-programming.rb</a></p>
<p class="diigo-description">A lovely strange loop of a post: a literate program about literate programming. Thanks to Larry Marburger for pointing it out to me.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/programming">programming</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/literate">literate</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a></p>
</li>
<li>
<p class="diigo-link"><a href="https://github.com/sconover/wrong">sconover/wrong &#8211; GitHub</a></p>
<p class="diigo-description">Very cool alternative for writing assertions in Ruby tests.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/testing">testing</a>             <a href="http://www.diigo.com/user/avdigrimm/tdd">tdd</a>             <a href="http://www.diigo.com/user/avdigrimm/bdd">bdd</a>             <a href="http://www.diigo.com/user/avdigrimm/rspec">rspec</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/assertions">assertions</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">if you can write it in Ruby, Wrong can make a sensible failure message out of it</div>
</p></div>
</li>
</ul>
</li>
</ul>
<p class="diigo-ps">Posted from <a href="http://www.diigo.com">Diigo</a>. The rest of my favorite links are <a href="http://www.diigo.com/user/avdigrimm">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/04/10/linkdump-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
