<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>David Chelimsky: Tag rspec</title>
    <link>http://blog.davidchelimsky.net/articles/tag/rspec?tag=rspec</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>on software in process and practice</description>
    <item>
      <title>new controller examples</title>
      <description>&lt;p&gt;There&amp;#8217;s been a lot of discussion about &lt;i&gt;clarity over &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/i&gt; lately. This is something that I&amp;#8217;ve been espousing for some time, but recent posts by &lt;a href="http://blog.jayfields.com/2008/05/testing-duplicate-code-in-your-tests.html"&gt;Jay Fields&lt;/a&gt;, &lt;a href="http://lindsaar.net/2008/6/24/tip-24-being-clever-in-specs-is-for-dummies"&gt;Mikel Lindsaar&lt;/a&gt; and &lt;a href="http://dannorth.net/2008/06/let-your-examples-flow"&gt;Dan North&lt;/a&gt; have gotten me thinking about it again with more focus.&lt;/p&gt;


	&lt;p&gt;With this in mind, I&amp;#8217;ve been refining the examples generated for restful controllers when you run &lt;code&gt;script/generate rspec_scaffold&lt;/code&gt; with the &lt;a href="http://github.com/dchelimsky/rspec-rails"&gt;rspec-rails&lt;/a&gt; plugin. I&amp;#8217;ve got them now where I&amp;#8217;m pretty happy with them, but I&amp;#8217;m curious to hear what you think. I&amp;#8217;m not going to tell you what I changed or what to look for, I&amp;#8217;m just going to ask you to look it over and post your comments.&lt;/p&gt;


	&lt;p&gt;There are two listings: the generated code and the output you get from running the examples. Thanks in advance for any feedback.&lt;/p&gt;&lt;h3&gt;script/generate rspec_scaffold account&lt;/h3&gt;


&lt;pre&gt;
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe AccountsController do

  def mock_account(stubs={})
    stubs = {
      :save =&amp;gt; true,
      :update_attributes =&amp;gt; true,
      :destroy =&amp;gt; true,
      :to_xml =&amp;gt; ''
    }.merge(stubs)
    @mock_account ||= mock_model(Account, stubs)
  end

  describe "responding to GET /accounts" do

    it "should succeed" do
      Account.stub!(:find)
      get :index
      response.should be_success
    end

    it "should render the 'index' template" do
      Account.stub!(:find)
      get :index
      response.should render_template('index')
    end

    it "should find all accounts" do
      Account.should_receive(:find).with(:all)
      get :index
    end

    it "should assign the found accounts for the view" do
      Account.should_receive(:find).and_return([mock_account])
      get :index
      assigns[:accounts].should == [mock_account]
    end

  end

  describe "responding to GET /accounts.xml" do

    before(:each) do
      request.env["HTTP_ACCEPT"] = "application/xml" 
    end

    it "should succeed" do
      Account.stub!(:find).and_return([])
      get :index
      response.should be_success
    end

    it "should find all accounts" do
      Account.should_receive(:find).with(:all).and_return([])
      get :index
    end

    it "should render the found accounts as xml" do
      Account.should_receive(:find).and_return(accounts = mock("Array of Accounts"))
      accounts.should_receive(:to_xml).and_return("generated XML")
      get :index
      response.body.should == "generated XML" 
    end

  end

  describe "responding to GET /accounts/1" do

    it "should succeed" do
      Account.stub!(:find)
      get :show, :id =&amp;gt; "1" 
      response.should be_success
    end

    it "should render the 'show' template" do
      Account.stub!(:find)
      get :show, :id =&amp;gt; "1" 
      response.should render_template('show')
    end

    it "should find the requested account" do
      Account.should_receive(:find).with("37")
      get :show, :id =&amp;gt; "37" 
    end

    it "should assign the found account for the view" do
      Account.should_receive(:find).and_return(mock_account)
      get :show, :id =&amp;gt; "1" 
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to GET /accounts/1.xml" do

    before(:each) do
      request.env["HTTP_ACCEPT"] = "application/xml" 
    end

    it "should succeed" do
      Account.stub!(:find).and_return(mock_account)
      get :show, :id =&amp;gt; "1" 
      response.should be_success
    end

    it "should find the account requested" do
      Account.should_receive(:find).with("37").and_return(mock_account)
      get :show, :id =&amp;gt; "37" 
    end

    it "should render the found account as xml" do
      Account.should_receive(:find).and_return(mock_account)
      mock_account.should_receive(:to_xml).and_return("generated XML")
      get :show, :id =&amp;gt; "1" 
      response.body.should == "generated XML" 
    end

  end

  describe "responding to GET /accounts/new" do

    it "should succeed" do
      get :new
      response.should be_success
    end

    it "should render the 'new' template" do
      get :new
      response.should render_template('new')
    end

    it "should create a new account" do
      Account.should_receive(:new)
      get :new
    end

    it "should assign the new account for the view" do
      Account.should_receive(:new).and_return(mock_account)
      get :new
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to GET /accounts/1/edit" do

    it "should succeed" do
      Account.stub!(:find)
      get :edit, :id =&amp;gt; "1" 
      response.should be_success
    end

    it "should render the 'edit' template" do
      Account.stub!(:find)
      get :edit, :id =&amp;gt; "1" 
      response.should render_template('edit')
    end

    it "should find the requested account" do
      Account.should_receive(:find).with("37")
      get :edit, :id =&amp;gt; "37" 
    end

    it "should assign the found Account for the view" do
      Account.should_receive(:find).and_return(mock_account)
      get :edit, :id =&amp;gt; "1" 
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to POST /accounts" do

    describe "with successful save" do

      it "should create a new account" do
        Account.should_receive(:new).with({'these' =&amp;gt; 'params'}).and_return(mock_account)
        post :create, :account =&amp;gt; {:these =&amp;gt; 'params'}
      end

      it "should assign the created account for the view" do
        Account.stub!(:new).and_return(mock_account)
        post :create, :account =&amp;gt; {}
        assigns(:account).should equal(mock_account)
      end

      it "should redirect to the created account" do
        Account.stub!(:new).and_return(mock_account)
        post :create, :account =&amp;gt; {}
        response.should redirect_to(account_url(mock_account))
      end

    end

    describe "with failed save" do

      it "should create a new account" do
        Account.should_receive(:new).with({'these' =&amp;gt; 'params'}).and_return(mock_account(:save =&amp;gt; false))
        post :create, :account =&amp;gt; {:these =&amp;gt; 'params'}
      end

      it "should assign the invalid account for the view" do
        Account.stub!(:new).and_return(mock_account(:save =&amp;gt; false))
        post :create, :account =&amp;gt; {}
        assigns(:account).should equal(mock_account)
      end

      it "should re-render the 'new' template" do
        Account.stub!(:new).and_return(mock_account(:save =&amp;gt; false))
        post :create, :account =&amp;gt; {}
        response.should render_template('new')
      end

    end

  end

  describe "responding to PUT /accounts/1" do

    describe "with successful update" do

      it "should find the requested account" do
        Account.should_receive(:find).with("37").and_return(mock_account)
        put :update, :id =&amp;gt; "37" 
      end

      it "should update the found account" do
        Account.stub!(:find).and_return(mock_account)
        mock_account.should_receive(:update_attributes).with({'these' =&amp;gt; 'params'})
        put :update, :id =&amp;gt; "1", :account =&amp;gt; {:these =&amp;gt; 'params'}
      end

      it "should assign the found account for the view" do
        Account.stub!(:find).and_return(mock_account)
        put :update, :id =&amp;gt; "1" 
        assigns(:account).should equal(mock_account)
      end

      it "should redirect to the account" do
        Account.stub!(:find).and_return(mock_account)
        put :update, :id =&amp;gt; "1" 
        response.should redirect_to(account_url(mock_account))
      end

    end

    describe "with failed update" do

      it "should find the requested account" do
        Account.should_receive(:find).with("37").and_return(mock_account(:update_attributes =&amp;gt; false))
        put :update, :id =&amp;gt; "37" 
      end

      it "should update the found account" do
        Account.stub!(:find).and_return(mock_account)
        mock_account.should_receive(:update_attributes).with({'these' =&amp;gt; 'params'})
        put :update, :id =&amp;gt; "1", :account =&amp;gt; {:these =&amp;gt; 'params'}
      end

      it "should assign the found account for the view" do
        Account.stub!(:find).and_return(mock_account(:update_attributes =&amp;gt; false))
        put :update, :id =&amp;gt; "1" 
        assigns(:account).should equal(mock_account)
      end

      it "should re-render the 'edit' template" do
        Account.stub!(:find).and_return(mock_account(:update_attributes =&amp;gt; false))
        put :update, :id =&amp;gt; "1" 
        response.should render_template('edit')
      end

    end

  end

  describe "responding to DELETE /accounts/1" do

    it "should find the account requested" do
      Account.should_receive(:find).with("37").and_return(mock_account)
      delete :destroy, :id =&amp;gt; "37" 
    end

    it "should call destroy on the found account" do
      Account.stub!(:find).and_return(mock_account)
      mock_account.should_receive(:destroy)
      delete :destroy, :id =&amp;gt; "1" 
    end

    it "should redirect to the accounts list" do
      Account.stub!(:find).and_return(mock_account)
      delete :destroy, :id =&amp;gt; "1" 
      response.should redirect_to(accounts_url)
    end

  end

end
&lt;/pre&gt;

	&lt;h3&gt;script/spec spec/controllers/accounts_controller_spec.rb -fn&lt;/h3&gt;


&lt;pre&gt;
AccountsController
  responding to GET /accounts
    should succeed
    should render the 'index' template
    should find all accounts
    should assign the found accounts for the view
  responding to GET /accounts.xml
    should succeed
    should find all accounts
    should render the found accounts as xml
  responding to GET /accounts/1
    should succeed
    should render the 'show' template
    should find the requested account
    should assign the found account for the view
  responding to GET /accounts/1.xml
    should succeed
    should find the account requested
    should render the found account as xml
  responding to GET /accounts/new
    should succeed
    should render the 'new' template
    should create a new account
    should assign the new account for the view
  responding to GET /accounts/1/edit
    should succeed
    should render the 'edit' template
    should find the requested account
    should assign the found Account for the view
  responding to POST /accounts
    with successful save
      should create a new account
      should assign the created account for the view
      should redirect to the created account
    with failed save
      should create a new account
      should assign the invalid account for the view
      should re-render the 'new' template
  responding to PUT /accounts/1
    with successful update
      should find the requested account
      should update the found account
      should assign the found account for the view
      should redirect to the account
    with failed update
      should find the requested account
      should update the found account
      should assign the found account for the view
      should re-render the 'edit' template
  responding to DELETE /accounts/1
    should find the account requested
    should call destroy on the found account
    should redirect to the accounts list
&lt;/pre&gt;</description>
      <pubDate>Tue, 01 Jul 2008 00:02:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:5c7df2e9-63ce-4f06-a330-f68ad68c405d</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/07/01/new-controller-examples</link>
      <category>rspec</category>
      <category>rails</category>
      <category>generator</category>
      <category>clarity</category>
      <category>DRY</category>
    </item>
    <item>
      <title>Slides from RailsConf</title>
      <description>&lt;p&gt;Here are the &lt;a href="http://blog.davidchelimsky.net/files/IntegrationTestingWithRSpecStoryRunner.RailsConf.2008.pdf"&gt;slides&lt;/a&gt; from my session at RailsConf on &lt;a href="http://en.oreilly.com/rails2008/public/schedule/detail/2055"&gt;Integration Testing With RSpec&amp;#8217;s Story Runner&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 16 Jun 2008 10:10:38 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:3cd915f1-f5d9-48e9-aa00-97c91bc3a121</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/06/16/slides-from-railsconf</link>
      <category>rspec</category>
      <category>railsconf</category>
      <category>slides</category>
    </item>
    <item>
      <title>Thoughts on the Dance-Off</title>
      <description>&lt;p&gt;In his &lt;a href="http://en.oreilly.com/rails2008/public/schedule/detail/1833"&gt;Great Test Framework Dance-Off&lt;/a&gt; at &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt;, &lt;a href="http://blog.hasmanythrough.com/"&gt;Josh Susser&lt;/a&gt; compared &lt;a href="http://rspec.info"&gt;rspec&lt;/a&gt; with &lt;a href="http://rubyforge.org/projects/test-spec/"&gt;test/spec&lt;/a&gt; and &lt;a href="http://www.thoughtbot.com/projects/shoulda"&gt;shoulda&lt;/a&gt;. All in all I&amp;#8217;d say he was very fair in his comparisons and I&amp;#8217;d recommend checking out his &lt;a href="http://hasmanythrough.com/gtfdo/gtfdo.pdf"&gt;slides&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;There were a couple of dings Josh handed rspec and I&amp;#8217;d like to respond to them. This is not intended to sell you on using rspec if you&amp;#8217;re not already using it. In fact, you&amp;#8217;ll see that I agree with a some of Josh&amp;#8217;s criticisms.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;d much rather see developers using frameworks like test/spec and shoulda than not using anything more expressive than test/unit out of the box, but I also cringe when I hear that someone chose a different framework for reasons that are based on inaccurate or incomplete information. I take full responsibility for that. If you&amp;#8217;re basing decisions on inaccurate or incomplete information it&amp;#8217;s because I haven&amp;#8217;t made the accurate and complete information available to you. This post is one step towards addressing that problem.&lt;/p&gt;&lt;h3&gt;Performance&lt;/h3&gt;


	&lt;p&gt;rspec currently runs slower than test/unit and the lightweight frameworks that sit on top of test/unit like test/spec and shoulda. Fortunately, this is something that can be addressed and will become a priority for us in the coming months.&lt;/p&gt;


	&lt;h3&gt;Underlying Complexity&lt;/h3&gt;


	&lt;p&gt;rspec is admittedly a complex and weighty beast. I think this is the result of several problems for which we are starting to look at solutions. We&amp;#8217;ve already started to take some steps towards reducing the amount of code that gets loaded (formatters are lazy loaded &amp;#8211; only the ones you use get loaded) and we have more work to do on that front.&lt;/p&gt;


	&lt;p&gt;There are also some efficiencies we can gain by merging the example group and story runners. Right now they both have some good things and some bad, and merging them should give us an opporunity to reduce the bad and take advantage of the good.&lt;/p&gt;


	&lt;p&gt;For me, the biggest issue is the lack of a rich, formalized extension &lt;span class="caps"&gt;API&lt;/span&gt;. There are some extension points we&amp;#8217;ve exposed and documented, but this can definitely be improved.&lt;/p&gt;


	&lt;p&gt;This is going to be a priority for me in the coming months. I think that once we have that in place, we can start to pull out some of the weight in rspec into plugins that get published separately in much the same vain as Rails and Merb are doing now.&lt;/p&gt;


	&lt;h3&gt;Custom Matchers&lt;/h3&gt;


	&lt;p&gt;In Josh&amp;#8217;s talk he pointed out that you can create custom assertions in 4 lines in test/unit frameworks while in rspec it took 30 or so lines. He did point out that the 30 line approach gives you far more control over error messages and that it covers the positive and negative matchers in one shot, but also commented that this extra power comes at a cost.&lt;/p&gt;


	&lt;p&gt;What Josh didn&amp;#8217;t know at the time, and this is definitely worthy of a ding for us not documenting things well enough, is rspec&amp;#8217;s &lt;code&gt;simple_matcher&lt;/code&gt; method that let&amp;#8217;s you create simple matchers in just a few lines. Here&amp;#8217;s the example in test/unit from Josh&amp;#8217;s talk:&lt;/p&gt;


&lt;pre&gt;
def assert_sorted(actual, message=nil, &amp;#38;block) 
  expected = actual.sort(&amp;#38;block) 
  assert_equal expected, actual, "Order is wrong:" 
end 
assert_sorted(tags) { |a,b| a.name &amp;lt;=&amp;gt; b.name }
&lt;/pre&gt;

	&lt;p&gt;And here&amp;#8217;s the same thing with &lt;code&gt;simple_matcher&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;
def be_sorted
  simple_matcher("a sorted list") {|actual| actual.sort == actual}
end
[1,2,3].should be_sorted
&lt;/pre&gt;

	&lt;p&gt;The block is handed the actual value. If the block returns true, the expectation passes. If it returns false, it fails with the following message:&lt;/p&gt;


&lt;pre&gt;
expected "a sorted list" but got [1, 3, 2]
&lt;/pre&gt;

	&lt;p&gt;If you say &lt;code&gt;[1,2,3].should_not be_sorted&lt;/code&gt; you&amp;#8217;d get this message instead=:&lt;/p&gt;


&lt;pre&gt;
expected not to get "a sorted list", but got [1, 2, 3]
&lt;/pre&gt;

	&lt;p&gt;As of now, you don&amp;#8217;t get any control over the failure message other than the string you pass to the &lt;code&gt;simple_matcher&lt;/code&gt; method, but I plan to add an optional hash that, if present, will give you more granular control over that message.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;FYI&lt;/span&gt; &amp;#8211; Josh was kind enough to &lt;a href="http://blog.hasmanythrough.com/2008/6/1/the-great-test-framework-dance-off"&gt;post this on his blog&lt;/a&gt; when I sent it to him. Thanks for that Josh.&lt;/p&gt;


	&lt;h3&gt;Macros&lt;/h3&gt;


	&lt;p&gt;Josh really likes the fact that shoulda ships with a bunch of macros like &lt;code&gt;should_only_allow_numeric_values_for&lt;/code&gt; and &lt;code&gt;should_render_template&lt;/code&gt;. This allows you to structure contexts like this (from the shoulda website):&lt;/p&gt;


&lt;pre&gt;
context "on GET to :show for first record" do
  setup do
    get :show, :id =&amp;gt; 1
  end

  should_assign_to :user
  should_respond_with :success
  should_render_template :show
  should_not_set_the_flash

  should "do something else really cool" do
    assert_equal 1, assigns(:user).id
  end
end
&lt;/pre&gt;

	&lt;p&gt;This is awesome stuff, and rspec-rails definitely lacks a built in set of macros like this. You can use technoweenie&amp;#8217;s &lt;a href="http://github.com/technoweenie/rspec_on_rails_on_crack"&gt;rspec_on_rails_on_crack&lt;/a&gt; plugin, does, however, to create rspec example groups like this:&lt;/p&gt;


&lt;pre&gt;
describe ThingsController, "GET #index" do
  fixtures :things

  act! { get :index }

  before do
    @things = []
    Thing.stub!(:find).with(:all).and_return(@things)
  end

  it_assigns :things
  it_renders :template, :index
end
&lt;/pre&gt;

	&lt;p&gt;You can also create your own custom macro-level matchers quite simply. Take shoulda&amp;#8217;s &lt;code&gt;should_respond_with :success&lt;/code&gt; from the example above. Here&amp;#8217;s how you&amp;#8217;d define that in rspec:&lt;/p&gt;


&lt;pre&gt;
module ControllerExampleGroupHelper
  module ClassMethods
    def should_respond_with(expected_response)
      it "should respond with #{expected_response}" do
        response.should be(expected_response)
      end
    end
  end

  class &amp;lt;&amp;lt; self
    def included(mod)
      mod.extend ClassMethods
    end
  end
end

Spec::Runner.configure do |config|
  config.include(ControllerExampleGroupHelper, :type =&amp;gt; :controller)
end
&lt;/pre&gt;

	&lt;p&gt;This adds the &lt;code&gt;should_respond_with&lt;/code&gt; method to all of your controller example groups. Obviously, you can just add methods to the &lt;code&gt;ControllerExampleGroupHelper::ClassMethods&lt;/code&gt; module and make them available as well.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how you might use this one:&lt;/p&gt;


&lt;pre&gt;
describe ThingsController do
  context "handling GET /things/1" do
    before(:each) { get :show, :id =&amp;gt; "1" }
    should_respond_with :success
  end
end
&lt;/pre&gt;

	&lt;p&gt;This outputs the following:&lt;/p&gt;


&lt;pre&gt;
ThingsController handling GET /things/1
- should respond with success
&lt;/pre&gt;

	&lt;p&gt;Of course, what we really need is an rspec-shoulda plugin that ships all of these for you. Ideally this could be done by simply making the shoulda macros available in rspec example groups, but my first impression is that shoulda is too tightly tied to test/unit to do that. I&amp;#8217;m looking into that possibility though.&lt;/p&gt;


	&lt;h3&gt;In Summary&lt;/h3&gt;


	&lt;p&gt;I&amp;#8217;m excited to see that rspec is inspiring other frameworks and that they are challenging rspec to improve on itself. Look for such improvements over the coming months.&lt;/p&gt;


	&lt;p&gt;I think that whether you choose to use rspec, shoulda, rspec&amp;#8217;s mocks or mocha or flexmock, etc, etc, this is a great time for testing frameworks in Ruby and I&amp;#8217;m excited to be part of this r-evolution.&lt;/p&gt;</description>
      <pubDate>Sat, 07 Jun 2008 15:43:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:1adc92f0-c2b4-4c21-a0a8-cea56f9aeb89</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/06/07/thoughts-on-the-dance-off</link>
      <category>rspec</category>
    </item>
    <item>
      <title>RSpec waving 'bye bye' to implicit module inclusion</title>
      <description>&lt;p&gt;Until sometime very soon, when you describe a module in RSpec using this syntax:&lt;/p&gt;


&lt;pre&gt;describe SomeModule do
  ...
end
&lt;/pre&gt;

	&lt;p&gt;RSpec implicitly includes that module in the example group. This allows you to do this:&lt;/p&gt;


&lt;pre&gt;describe CatLikeBehaviour do
  it "should say 'meow' when it greets you" do
    say_hello.should == 'meow'
  end
end

module CatLikeBehaviour do
  def say_hello
    'meow'
  end
end
&lt;/pre&gt;

	&lt;p&gt;As is often the case with things implicit, this actually turns out to be a problem. The problem revealed itself most notably when an RSpec user reported that a &lt;code&gt;describe()&lt;/code&gt; method in a module he was using was conflicting with RSpec&amp;#8217;s &lt;code&gt;describe()&lt;/code&gt; method.&lt;/p&gt;


	&lt;p&gt;One response to that thread suggested that using &lt;code&gt;describe()&lt;/code&gt; in a module might be too generic, but I think that really hides the point. Imagine how frustrated you would get if you had examples of a module with a &lt;code&gt;current?&lt;/code&gt; method and we decided to add a &lt;code&gt;current?&lt;/code&gt; method to &lt;code&gt;Spec::Example::ExampleGroupMethods&lt;/code&gt;. You&amp;#8217;d suddenly start seeing those examples fail with stack traces eminating from RSpec instead of your code. Not good.&lt;/p&gt;


	&lt;p&gt;And so, we are going to be removing this feature.&lt;/p&gt;


	&lt;p&gt;With the 1.1.4 release, you get a warning any time that the example calls a method on &lt;code&gt;self&lt;/code&gt; that is part of the included module. Soon it will be removed entirely.&lt;/p&gt;


	&lt;h3&gt;rails helper examples&lt;/h3&gt;


	&lt;p&gt;The biggest impact of this is going to be felt in rspec-rails helper examples. There are two remedies that you have if you&amp;#8217;ve got examples that send messages to &lt;code&gt;self&lt;/code&gt; that should be going to another object:&lt;/p&gt;


	&lt;p&gt;1. use the new &lt;code&gt;helper&lt;/code&gt; object provided by &lt;code&gt;HelperExampleGroup&lt;/code&gt;&lt;/p&gt;


&lt;pre&gt;describe DateHelper do
  it "should format the date as mm/dd/yyyy" do
    helper.format_date(Date.new(2008, 5, 31)).should == '05/31/2008'
  end
end
&lt;/pre&gt;

	&lt;p&gt;The &lt;code&gt;helper&lt;/code&gt; object is an instance of &lt;code&gt;ActionView::Base&lt;/code&gt; with the named module included in it, so it has access to everything else that it should have.&lt;/p&gt;


	&lt;p&gt;2. include the module explicitly&lt;/p&gt;


&lt;pre&gt;describe DateHelper do
  include DateHelper
  it "should format the date as mm/dd/yyyy" do
    format_date(Date.new(2008, 5, 31)).should == '05/31/2008'
  end
end
&lt;/pre&gt;

	&lt;p&gt;My recommendation is definitely the first option as I find it more expressive.&lt;/p&gt;


	&lt;p&gt;I realize this is &lt;span class="caps"&gt;API&lt;/span&gt; changing and backward-compatibility breaking, but this is one of those cases where, at least in my view, the pain is justified by the result.&lt;/p&gt;</description>
      <pubDate>Thu, 29 May 2008 10:31:26 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:76f4a8ea-fcce-4e52-9764-46b75ab9814e</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/05/29/rspec-waving-bye-bye-to-implicit-module-inclusion</link>
      <category>rspec</category>
    </item>
    <item>
      <title>RSpec-1.1.4</title>
      <description>&lt;p&gt;We released RSpec-1.1.4 today. It&amp;#8217;s mostly a maintenance release but there are a few of cool new features that you may want to know about and take advantage of.&lt;/p&gt;


	&lt;h3&gt;hash_including&lt;/h3&gt;


	&lt;p&gt;One thing that has always been a drag is having to specify every key/value pair in a hash that is received as an argument. This is especially painful in Rails controller examples because Rails adds some data to the hash and the examples really don&amp;#8217;t care about that extra data.&lt;/p&gt;


	&lt;p&gt;Enter &lt;code&gt;hash_including()&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;This is a mock argument matcher that let&amp;#8217;s you expect a hash including certain key/value pairs regardless of anything else that shows up in the hash. So instead of:&lt;/p&gt;


&lt;pre&gt;
account.should_receive(:deposit).with({:amount =&amp;gt; 37.42, :date =&amp;gt; anything()})
&lt;/pre&gt;

	&lt;p&gt;you can just say:&lt;/p&gt;


&lt;pre&gt;
account.should_receive(:deposit).with(hash_including(:amount =&amp;gt; 37.42))
&lt;/pre&gt;

	&lt;p&gt;and keep the example focused on what you&amp;#8217;re really interested in&lt;/p&gt;


	&lt;p&gt;Thanks to &lt;a href="http://talklikeaduck.denhaven2.com/"&gt;Rick DeNatale&lt;/a&gt; who submitted this feature request and the patch to implement it.&lt;/p&gt;


	&lt;h3&gt;The heckler returns&lt;/h3&gt;


	&lt;p&gt;RSpec wasn&amp;#8217;t correctly supporting heckle for a while but the spec-heckler is back in action. For those unfamiliar, you can read about heckle at &lt;a href="http://blog.zenspider.com/2007/06/heckle-version-141-has-been-re.html"&gt;zenspider&amp;#8217;s blog&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how you heckle your Animal model in your PetStore app:&lt;/p&gt;


&lt;pre&gt;
spec spec/models/animal_spec.rb --heckle Animal
&lt;/pre&gt;

	&lt;p&gt;Thanks to &lt;a href="http://tarvainen.wordpress.com/"&gt;Antti Tarvainen&lt;/a&gt; for resurrecting this one.&lt;/p&gt;


	&lt;h3&gt;stub_model&lt;/h3&gt;


	&lt;p&gt;This is for rails developers who like writing view examples with &lt;code&gt;mock_model()&lt;/code&gt; but are sick and tired of having to stub every single attribute that gets referenced in a view.&lt;/p&gt;


	&lt;p&gt;Instead of creating a mock object like &lt;code&gt;mock_model()&lt;/code&gt; does, &lt;code&gt;stub_model()&lt;/code&gt; creates an instance of a real model class, but cuts off it&amp;#8217;s connection to the database, raising an error any time it tries to connect to the database.&lt;/p&gt;


	&lt;p&gt;This is inspired by projects like &lt;a href="http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database"&gt;unit_record&lt;/a&gt; and &lt;a href="http://agilewebdevelopment.com/plugins/nulldb"&gt;NullDB&lt;/a&gt;, but let&amp;#8217;s you do things at a more granular level &amp;#8211; allowing you to hit the db in some cases (where you think you really need it) and not in others.&lt;/p&gt;


	&lt;p&gt;Of course, you may prefer to the sort of &amp;#8220;protection&amp;#8221; you get from those projects, which ensure that no code touches the DB at all. If you do, have at it. This is just another option for you.&lt;/p&gt;


	&lt;h3&gt;All this and more&lt;/h3&gt;


	&lt;p&gt;These are just a few of the issues addressed in 1.1.4. For more information, check out the &lt;a href="http://rspec.info/changes.html"&gt;changelog&lt;/a&gt; and &lt;a href="http://rspec.lighthouseapp.com/projects/5645"&gt;lighthouse&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 27 May 2008 01:07:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9e423c98-ab13-4d7e-84ec-a3b8eac1620a</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>railsconf</category>
    </item>
    <item>
      <title>RSpec at github</title>
      <description>&lt;p&gt;After a few months of exploring git and hosting &lt;a href="http://rspec.info"&gt;RSpec&amp;#8217;s&lt;/a&gt; git repository at &lt;a href="http://github.com/dchelimsky/rspec"&gt;github&lt;/a&gt;, we&amp;#8217;re happy to announce that github is now RSpec&amp;#8217;s official home for Source Code Management.&lt;/p&gt;


	&lt;p&gt;Tracking will continue to live at the &lt;a href="http://rspec.lighthouseapp.com"&gt;lighthouse&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;We will continue to release gems to &lt;a href="Rubyforge"&gt;http://rubyforge.org/projects/rspec&lt;/a&gt;, but we will no longer be committing changes to the subversion repository there. For Rails users who are using the rspec plugins for Rails, edge rails now supports git-hosted plugins.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ve broken the project up into four separate repositories:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://github.com/dchelimsky/rspec/wikis/home"&gt;rspec&lt;/a&gt; for the rspec gem/plugin&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://github.com/dchelimsky/rspec-rails/wikis/home"&gt;rspec-rails&lt;/a&gt; for the rspec-rails gem/plugin (formerly rspec_on_rails)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://github.com/dchelimsky/rspec-tmbundle/wikis/home"&gt;rspec-tmbundle&lt;/a&gt; for the TextMate bundle&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://github.com/dchelimsky/rspec-dev/wikis/home"&gt;rspec-dev&lt;/a&gt; for developers/contributors&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;See the wikis for each repository for more information about building, installing and contributing to the project.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Apr 2008 13:41:24 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9c54a1d1-9f2c-4872-8807-dd11cb4818ea</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/04/09/rspec-at-github</link>
      <category>rspec</category>
      <category>git</category>
    </item>
    <item>
      <title>Welcome Pat Maddox</title>
      <description>&lt;p&gt;I&amp;#8217;m pleased to announce that &lt;a href="http://evang.eli.st/blog"&gt;Pat Maddox&lt;/a&gt; is joining the &lt;a href="rspec.info"&gt;RSpec&lt;/a&gt; Development Team.&lt;/p&gt;


	&lt;p&gt;As you may already know, Pat has been contributing great patches and actively participating on the &lt;a href="http://rubyforge.org/mailman/listinfo/rspec-users"&gt;rspec-users&lt;/a&gt; and &lt;a href="http://rubyforge.org/mailman/listinfo/rspec-devel"&gt;rspec-devel&lt;/a&gt; mailing lists for quite some time. He has demonstrated a deep understanding of Behaviour Driven Development in general, and specifically as it applies to Rails, which has certainly posed some of the more interesting questions on our mailing lists.&lt;/p&gt;


	&lt;p&gt;We are all excited to have Pat on board and look forward to his continued contribution.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Apr 2008 09:27:31 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:98043e70-7f55-4910-9fa6-4910de330480</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/04/04/welcome-pat-maddox</link>
      <category>rspec</category>
    </item>
    <item>
      <title>limiting scope of autotest</title>
      <description>&lt;p&gt;If you use &lt;a href="http://zentest.rubyforge.org/ZenTest/classes/Autotest.html"&gt;autotest&lt;/a&gt; with &lt;a href="http://rspec.info"&gt;rspec&lt;/a&gt; or test/unit, you&amp;#8217;ve probably had this experience (or one like it):&lt;/p&gt;


	&lt;p&gt;You want to add some new behaviour to a model object, so you write a spec, watch it fail, make it pass, and then wait until the entire spec suite runs. Even if you&amp;#8217;ve got a fast-running suite, this can be painful sometimes.&lt;/p&gt;


	&lt;p&gt;Wouldn&amp;#8217;t it be great if you could limit the scope of what directories autotest observes?  Well it turns out that you can! Recent releases of ZenTest include a find_directories attribute on the autotest object. Just add this to your .autotest file:&lt;/p&gt;


&lt;pre&gt;
Autotest.add_hook :initialize do |at|
  unless ARGV.empty?
    at.find_directories = ARGV.dup
  end
end
&lt;/pre&gt;

	&lt;p&gt;and then you can say:&lt;/p&gt;


&lt;pre&gt;
autotest app/models spec/models
&lt;/pre&gt;

	&lt;p&gt;and it will only observe those directories. This is nice and flexible, but I find that most of the time I&amp;#8217;m wanting pairs like that: app/models and spec/models, or app/views/accounts and spec/views/accounts. In that case, I&amp;#8217;d really like to just say:&lt;/p&gt;


&lt;pre&gt;
autotest models
&lt;/pre&gt;

	&lt;p&gt;To accomplish that you can do this to the hook instead:&lt;/p&gt;


&lt;pre&gt;
Autotest.add_hook :initialize do |at|
  unless ARGV.empty?
    at.find_directories = ["spec/#{ARGV.first}","app/#{ARGV.first}"]
  end
end
&lt;/pre&gt;

	&lt;p&gt;Want the best of both worlds? Try this:&lt;/p&gt;


&lt;pre&gt;
Autotest.add_hook :initialize do |at|
  unless ARGV.empty?
    at.find_directories = ARGV.length == 1 ? ["spec/#{ARGV.first}","app/#{ARGV.first}"] : ARGV.dup
  end
end
&lt;/pre&gt;

	&lt;p&gt;The only limitation of this is that it&amp;#8217;s based on directories, not files. Once in a while, when I&amp;#8217;m bootstrapping a new object, I&amp;#8217;ll keep the examples and the implementation in the same file until I&amp;#8217;ve got things fleshed out a bit the object is ready to play nice with others. In that case, I might like to just point autotest to that one file. I started working on a patch for this for ZenTest, but I&amp;#8217;m not sure it&amp;#8217;s worth the extra effort. What do you think?&lt;/p&gt;


	&lt;p&gt;Regardless &amp;#8211; happy auto-exemplifying!&lt;/p&gt;</description>
      <pubDate>Wed, 05 Mar 2008 02:07:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:7b63be47-39a5-428f-9a6f-13e2f1542a04</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/03/05/limiting-scope-of-autotest</link>
      <category>rspec</category>
      <category>bdd</category>
      <category>autotest</category>
    </item>
    <item>
      <title>RSpec-1.1.3 and ZenTest-3.9.1</title>
      <description>&lt;p&gt;ZenTest&amp;#8217;s last two releases are not compatible with previous versions of RSpec. This is &lt;strong&gt;good news&lt;/strong&gt; because Autotest now exposes better extension points for subclasses like those that ship with RSpec. Before, RSpec had to monkey patch Autotest to control the mappings of specs to files to run, and the list of files/directories to ignore. Now RSpec gets to use public methods (instead of instance variables) and documented hooks to do it&amp;#8217;s work.&lt;/p&gt;


	&lt;p&gt;In the long run, this will keep things more flexible for both RSpec and ZenTest. In the short run, the catch for you is that you have to use compatible versions of RSpec and ZenTest. They are:&lt;/p&gt;


&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;RSpec version&lt;/th&gt;&lt;th&gt;ZenTest version&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;= 1.1.1&lt;/td&gt;&lt;td&gt;&amp;lt;= 3.7.x&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1.1.2&lt;/td&gt;&lt;td&gt;3.8.x&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1.1.3&lt;/td&gt;&lt;td&gt;3.9.x&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</description>
      <pubDate>Mon, 04 Feb 2008 03:04:57 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:8f236be2-fa8c-4162-8590-d954d4cf8654</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/02/04/rspec-1-1-3-and-zentest-3-9-1</link>
      <category>rspec</category>
      <category>zentest</category>
      <category>autotest</category>
    </item>
    <item>
      <title>RSpec: new --pattern option</title>
      <description>&lt;p&gt;&lt;span style="color:red;font-weight:bold;"&gt;Updated on 27 May, 2008&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not in the habit of blogging every change we make to RSpec, but this one &lt;strong&gt;may&lt;/strong&gt; change the way your suite behaves if you have not been following convention.&lt;/p&gt;


	&lt;p&gt;As of RSpec&amp;#8217;s trunk revision 3246 there is a new command line option that lets you control the filename pattern to match. This allows you to restrict files that are loaded when running the spec command in the same way that you can with rake. It also means that helper files that you may depend on are no longer loaded implicitly.&lt;/p&gt;


	&lt;p&gt;The default is:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;"spec/**/*_spec.rb".
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;To get rspec to behave as it did before this change, use this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;--pattern "spec/**/*.rb" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If you prefer naming your spec files &amp;#8220;foo_example.rb&amp;#8221;, you can do this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;--pattern "spec/**/*_example.rb" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You can also supply multiple patterns (comma separated):&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;--pattern "spec/**/*_example.rb, spec/**/*_spec.rb" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This is a very handy way to avoid loading resource files (helpers, matchers, etc) except when you require them explicitly from other files.&lt;/p&gt;


	&lt;p&gt;This is currently only in trunk, but will be part of the next release.&lt;/p&gt;</description>
      <pubDate>Sun, 20 Jan 2008 13:04:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:962a4799-5c0f-4010-ba0b-933142dd23eb</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/01/20/rspec-new-pattern-option</link>
      <category>rspec</category>
    </item>
  </channel>
</rss>
