<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>opensoul.org - RSpec is getting too intimate with my code Changes</title>
  <id>tag:opensoul.org,2009:/2007/6/20/rspec-is-getting-too-intimate-with-my-code/changes</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://opensoul.org/2007/6/20/rspec-is-getting-too-intimate-with-my-code/changes.xml" rel="self" type="application/atom+xml"/>
  <link href="/2007/6/20/rspec-is-getting-too-intimate-with-my-code" rel="alternate" type="text/html"/>
  <updated>2007-06-20T07:56:00Z</updated>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2007-06-20:309:1</id>
    <updated>2007-06-20T07:56:00Z</updated>
    <link href="http://opensoul.org/2009/3/9/rspec-is-getting-too-intimate-with-my-code" rel="alternate" type="text/html"/>
    <title>RSpec is getting too intimate with my code</title>
<content type="html">&lt;p&gt;The theory is that tests are supposed to be agnostic of the implementation. This leads to less brittle tests and actually tests the outcome (or behavior).&lt;/p&gt;


	&lt;p&gt;With RSpec, I feel like the common approach of completely mocking your models to test your controllers ends up forcing you to look too much into the implementation of your controller.&lt;/p&gt;


	&lt;p&gt;Here is an example of a spec that is generated by the rspec_scaffold generator:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe ThingsController, &amp;quot;handling POST /things&amp;quot; do

  before do
    @params = {}
    @thing = mock_model(Thing, :to_param =&amp;gt; &amp;quot;1&amp;quot;, :save =&amp;gt; true)
    Thing.stub!(:new).and_return(@thing)
  end

  def do_post
    post :create, :thing =&amp;gt; @params
  end

  it &amp;quot;should create a new thing&amp;quot; do
    Thing.should_receive(:new).with(@params).and_return(@thing)
    do_post
  end

  it &amp;quot;should redirect to the new thing&amp;quot; do
    do_post
    response.should redirect_to(@thing)
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This by itself is not too bad, but the problem is that it peers too much into the controller to dictate how the model is used.  Why does it matter if my controller calls &lt;code&gt;Thing.new&lt;/code&gt;?  What if my controller decides to take the &lt;code&gt;Thing.create!&lt;/code&gt; and &lt;code&gt;rescue&lt;/code&gt; route? What if my model has a special initializer method, like &lt;code&gt;Thing.build_with_foo&lt;/code&gt;? My spec for &lt;em&gt;behavior&lt;/em&gt; should not fail if I change the implementation.&lt;/p&gt;


	&lt;p&gt;This problem gets even worse when you have nested resources and are creating multiple models per controller.  Some of my setup methods end up being 15 or more lines long and &lt;span class=&quot;caps&quot;&gt;VERY&lt;/span&gt; fragile.&lt;/p&gt;


	&lt;p&gt;RSpec&#8217;s intention is to completely isolate your controller logic from your models, which sounds good in theory, but almost runs against the grain for an integrated stack like Rails. Especially if you practice the skinny controller/fat model discipline, the amount of logic in the controller becomes very small, and the setup becomes huge.&lt;/p&gt;


	&lt;p&gt;So what&#8217;s a &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;-wannabe to do?  Taking a step back, the &lt;em&gt;behavior&lt;/em&gt; that I really want to test is not that my controller calls &lt;code&gt;Thing.new&lt;/code&gt;, but that given parameters &lt;em&gt;X&lt;/em&gt;, it creates a new thing and redirects to it.&lt;/p&gt;


	&lt;p&gt;Here&#8217;s the approach I&#8217;ve been taking:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# spec_helper.rb
def valid_thing_attrs(attrs = {})
  {:name =&amp;gt; 'Foo'}.merge(attrs)
end

# things_controller_spec.rb
describe ThingsController, &amp;quot;handling POST /things&amp;quot; do

  def do_post
    post :create, :thing =&amp;gt; valid_thing_attrs
  end

  it &amp;quot;should create a new thing&amp;quot; do
    lambda { do_post }.should change { Thing.count }.by(1)
  end

  it &amp;quot;should redirect to the new thing&amp;quot; do
    do_post
    response.should redirect_to(@thing)
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;My spec is now testing that posting certain attributes creates a new thing (in the database) and redirects to it. You&#8217;ll notice that I have a method called &lt;code&gt;valid_thing_attrs&lt;/code&gt;.  I don&#8217;t remember where I picked up this pattern, but it is something that has allowed me to minimize all of my test&#8217;s dependencies on the model.&lt;/p&gt;


	&lt;p&gt;My spec is now somewhat dependent on my model–and thus will break if my model gets hosed–but that is a small price to pay, in my opinion, for an implementation-agnostic spec with significantly less overhead.&lt;/p&gt;


	&lt;p&gt;What do you think?&lt;/p&gt;</content>  </entry>
</feed>
