Written by: steve ross on March 27th 2007

If you read my [post]/2007/02/07/rspec----behavior-driven-development/ on rSpec, you may infer that I am trying to track its development. Recently, there have been some changes in trunk worthy of mention.

In particular the context/specify syntax has changed to describe/it. The old specs won't break, but the new syntax is more about telling and not asking. The contrived example is:

  
      describe "A BlogController" do
        it "should load index page successfully"
          get :index
          response.should_be_success
        end
      end
  

I updated the earlier post to reflect the new syntax, restating the example, here's how it would read:

  
    describe "Given a request to change quantity, the CartController should" do
        include Stubs
        controller_name "carts"
        integrate_views

        setup do
            Cart.stub!(:new).and_return(stub_cart)
            LineItem.stub!(:find_by_id).and_return(stub_line_item)

            @cart = stub_cart
            @line_item = stub_line_item

            post :change_quantity, {:id => 1, :quantity => 1}
        end

          it "respond w/ success" do
            response.should be_success
          end

          it "assign extension_id" do
            assigns[:extension_id].should == "extension1"
          end

          it "assign line_item" do
            assigns[:line_item].should equal(@line_item)
          end

          it "update the html (using rjs)" do
            controller.should have_rjs(:replace_html,
              'cartstatus',
              /1 item/)
            controller.should have_rjs(:replace_html,
              'cartstatus',
              /\$35\.00/)
          end
    end
    

Note that the code reads more like natural language. I am telling the code that "it should respond w/success". Having said what the controller (or model) should do, I then write code to make it so.

Of particular note to those who've tried rSpec is the removal of some syntactic sugar. That means where we used to say

  
foo.should_be(bar)
  

we now say

  
foo.should be(bar)
  

The key is that there is a space after "should." Same for:

  
foo.should_not be(baz)
  

Also note that "be" is not the same as "eql." If you are intending the same object, then use "be", for example:

  
foo.should be(true)
  

If you are expecting equality, say

  
foo.should eql('hello')
  

Give it a try!