<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>opensoul.org - Making RSpec concise Changes</title>
  <id>tag:opensoul.org,2009:/2008/11/10/making-rspec-concise/changes</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://opensoul.org/2008/11/10/making-rspec-concise/changes.xml" rel="self" type="application/atom+xml"/>
  <link href="/2008/11/10/making-rspec-concise" rel="alternate" type="text/html"/>
  <updated>2008-11-11T16:28:00Z</updated>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2008-11-11:499:2</id>
    <published>2008-11-10T03:07:00Z</published>
    <updated>2008-11-11T16:28:00Z</updated>
    <link href="http://opensoul.org/2008/11/10/making-rspec-concise" rel="alternate" type="text/html"/>
    <title>Making RSpec concise</title>
<content type="html">&lt;p&gt;A common criticism of &lt;a href=&quot;http://rspec.info&quot;&gt;RSpec&lt;/a&gt; is that it is very verbose. I don&#8217;t necessarily agree (or care), but I thought it would be fun to see how concise I could make my specs.&lt;/p&gt;


	&lt;p&gt;Here are some simple specs from a client project:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  before do
    @company = Company.new
  end

  it &amp;quot;should have many classifications&amp;quot; do
    @company.should have_many(:classifications)
  end

  it &amp;quot;should have many industries through companies&amp;quot; do
    @company.should have_many(:industries, :through =&amp;gt; :classifications)
  end

  it &amp;quot;should have many locations&amp;quot; do
    @company.should have_many(:locations)
  end

  it &amp;quot;should have many leads&amp;quot; do
    @company.should have_many(:leads)
  end

  it &amp;quot;should have many jobs&amp;quot; do
    @company.should have_many(:jobs)
  end

  it &amp;quot;should have many notes&amp;quot; do
    @company.should have_many(:notes)
  end

  it &amp;quot;should have many phones ordered by phone type position&amp;quot; do
    @company.should have_many(:phones, :as =&amp;gt; :phonable,
      :include =&amp;gt; :phone_type, :order =&amp;gt; 'phone_types.position')
  end

  it &amp;quot;should have many events&amp;quot; do
    @company.should have_many(:events)
  end

  it &amp;quot;should have many interests&amp;quot; do
    @company.should have_many(:interests)
  end

  it &amp;quot;should belong_to an exchange&amp;quot; do
    @company.should belong_to(:exchange)
  end

  it 'should belong_to a primary_contact' do
    @company.should belong_to(:primary_contact, :class_name =&amp;gt; 'Job')
  end

  it 'should have many articles' do
    @company.should have_many(:articles,
      :order =&amp;gt; 'articles.date DESC, articles.created_at DESC')
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;These specs check the declared associations on our company model &lt;a href=&quot;http://github.com/brandon/rspec-on-rails-matchers&quot;&gt;using some custom matchers&lt;/a&gt;. They are not very complicated, but are somewhat repetitive. Each example has a description that is basically a duplication of the implementation.&lt;/p&gt;


	&lt;h3&gt;Step 1: remove the description&lt;/h3&gt;


	&lt;p&gt;For a while now, RSpec has had the ability for matchers to be self describing. If you don&#8217;t pass a block to &lt;code&gt;#it&lt;/code&gt;, it uses the description provided by the matcher.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it do
  @company.should have_many(:jobs)
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;When that spec is run, it gives the output &lt;em&gt;&#8220;should have a has_many association called :jobs&#8221;&lt;/em&gt;. Depending on what you&#8217;re speccing, the built in description isn&#8217;t always clear, but in this case it&#8217;s great.&lt;/p&gt;


	&lt;p&gt;See &lt;a href=&quot;http://rspec.rubyforge.org/rspec/1.1.11/classes/Spec/Matchers.html#M000441&quot;&gt;#simple_matcher&lt;/a&gt; if you want to create custom matchers with useful error messages.&lt;/p&gt;


	&lt;h3&gt;Step 2: remove the subject&lt;/h3&gt;


	&lt;p&gt;So the duplication within each example is gone, but if you look at the full spec above, each example calls &lt;code&gt;@company.should&lt;/code&gt;. Accessing an instance variable isn&#8217;t what I would consider &#8220;duplication&#8221;, but thanks to a &lt;a href=&quot;http://github.com/dchelimsky/rspec/commit/dc51a976280b7d9638e9b87c3c7b3c13d3d0b207&quot;&gt;nifty new feature added to RSpec today&lt;/a&gt;, it&#8217;s now unnecessary noise.  We can simply call &lt;code&gt;#should&lt;/code&gt; within our example, and it will use a new instance of the described type as the &#8220;subject&#8221;.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  it do
    should have_many(:jobs)
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You can customize the subject if you don&#8217;t simply want a new instance.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company, 'validations' do
  subject { Company.new(valid_company_attributes) }

  it do
    should be_valid
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;ins&gt;Note: As &lt;a href=&quot;#comment-9459&quot;&gt;David Chelimsky points out in the comments&lt;/a&gt;, this is not released yet and is subject to change.&lt;/ins&gt;&lt;/p&gt;


	&lt;h3&gt;Step 3: One-liner&lt;/h3&gt;


	&lt;p&gt;Lastly, we can use the one line block:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  it { should have_many(:classifications) }
  it { should have_many(:events) }
  it { should have_many(:interests) }
  it { should have_many(:jobs) }
  it { should have_many(:leads) }
  it { should have_many(:locations) }
  it { should have_many(:notes) }
  it { should have_many(:articles, :order =&amp;gt; 'articles.date DESC, articles.created_at DESC') }
  it { should have_many(:industries, :through =&amp;gt; :classifications) }
  it { should have_many(:phones, :as =&amp;gt; :phonable, :include =&amp;gt; :phone_type, :order =&amp;gt; 'phone_types.position') }
  it { should belong_to(:exchange) }
  it { should belong_to(:primary_contact, :class_name =&amp;gt; 'Job') }
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That&#8217;s pretty sexy. I wasn&#8217;t able to do this with all of the specs in my app, but it worked with quite a few of them.&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2008-11-10:498:1</id>
    <updated>2008-11-10T02:52:43Z</updated>
    <link href="http://opensoul.org/2009/3/5/making-rspec-concise" rel="alternate" type="text/html"/>
    <title>Making RSpec concise</title>
<content type="html">&lt;p&gt;A common criticism of &lt;a href=&quot;http://rspec.info&quot;&gt;RSpec&lt;/a&gt; is that it is very verbose. I don&#8217;t necessarily agree (or care), but I thought it would be fun to see how concise I could make my specs.&lt;/p&gt;


	&lt;p&gt;Here are some simple specs from a client project:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  before do
    @company = Company.new
  end

  it &amp;quot;should have many classifications&amp;quot; do
    @company.should have_many(:classifications)
  end

  it &amp;quot;should have many industries through companies&amp;quot; do
    @company.should have_many(:industries, :through =&amp;gt; :classifications)
  end

  it &amp;quot;should have many locations&amp;quot; do
    @company.should have_many(:locations)
  end

  it &amp;quot;should have many leads&amp;quot; do
    @company.should have_many(:leads)
  end

  it &amp;quot;should have many jobs&amp;quot; do
    @company.should have_many(:jobs)
  end

  it &amp;quot;should have many notes&amp;quot; do
    @company.should have_many(:notes)
  end

  it &amp;quot;should have many phones ordered by phone type position&amp;quot; do
    @company.should have_many(:phones, :as =&amp;gt; :phonable, :include =&amp;gt; :phone_type, :order =&amp;gt; 'phone_types.position')
  end

  it &amp;quot;should have many events&amp;quot; do
    @company.should have_many(:events)
  end

  it &amp;quot;should have many interests&amp;quot; do
    @company.should have_many(:interests)
  end

  it &amp;quot;should belong_to an exchange&amp;quot; do
    @company.should belong_to(:exchange)
  end

  it 'should belong_to a primary_contact' do
    @company.should belong_to(:primary_contact, :class_name =&amp;gt; 'Job')
  end

  it 'should have many articles' do
    @company.should have_many(:articles, :order =&amp;gt; 'articles.date DESC, articles.created_at DESC')
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;These specs check the declared associations on our company model &lt;a href=&quot;http://github.com/brandon/rspec-on-rails-matchers&quot;&gt;using some custom matchers&lt;/a&gt;. They are not very complicated, but are somewhat repetitive. Each example has a description that is basically a duplication of the implementation.&lt;/p&gt;


	&lt;h3&gt;Step 1: remove the description&lt;/h3&gt;


	&lt;p&gt;For a while now, RSpec has had the ability for matchers to be self describing. If you don&#8217;t pass a block to &lt;code&gt;#it&lt;/code&gt;, it uses the description provided by the matcher.&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it do
    @company.should have_many(:jobs)
  end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;When that spec is run, it gives the output &#8220;should have a has_many association called :jobs&#8221;. Depending on what you&#8217;re speccing, the built in description isn&#8217;t always clear, but in this case it&#8217;s great.&lt;/p&gt;


	&lt;p&gt;See &lt;a href=&quot;http://rspec.rubyforge.org/rspec/1.1.11/classes/Spec/Matchers.html#M000441&quot;&gt;#simple_matcher&lt;/a&gt; if you want to create custom matchers with useful error messages.&lt;/p&gt;


	&lt;h3&gt;Step 2: remove the subject&lt;/h3&gt;


	&lt;p&gt;So the duplication within each example is gone, but if you look at the full spec above, each example calls &lt;code&gt;#should&lt;/code&gt; on &lt;code&gt;\@company&lt;/code&gt;. Accessing an instance variable isn&#8217;t what I would consider &#8220;duplication&#8221;, but thanks to a &lt;a href=&quot;http://github.com/dchelimsky/rspec/commit/dc51a976280b7d9638e9b87c3c7b3c13d3d0b207&quot;&gt;nifty new feature added to RSpec today&lt;/a&gt;, it&#8217;s now unnecessary noise.  We can simply call &lt;code&gt;#should&lt;/code&gt; within our example, and it will use the described type as the &lt;a href=&quot;&amp;lt;/p&quot;&gt;subject&lt;/a&gt;&amp;gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  it do
    should have_many(:jobs)
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Step 3: One-liner&lt;/h3&gt;


	&lt;p&gt;Lastly, we can use the one line block:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe Company do
  it { should have_many(:articles, :order =&amp;gt; 'articles.date DESC, articles.created_at DESC') }
  it { should have_many(:classifications) }
  it { should have_many(:events) }
  it { should have_many(:industries, :through =&amp;gt; :classifications) }
  it { should have_many(:interests) }
  it { should have_many(:jobs) }
  it { should have_many(:leads) }
  it { should have_many(:locations) }
  it { should have_many(:notes) }
  it { should have_many(:phones, :as =&amp;gt; :phonable, :include =&amp;gt; :phone_type, :order =&amp;gt; 'phone_types.position') }
  it { should belong_to(:exchange) }
  it { should belong_to(:primary_contact, :class_name =&amp;gt; 'Job') }
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That&#8217;s pretty sexy. I wasn&#8217;t able to do this with all of the specs in my app, but it worked with quite a few of them.&lt;/p&gt;</content>  </entry>
</feed>
