Blog

Friday, September 17, 2010

The Other RSpec Methods: #subject, #specify, and #let

Recently I switched to RSpec from Shoulda. This switch was driven mostly by this announcement explaining ThoughtBot's intention in providing matchers for RSpec, rather than a context framework. Here are three highlights from my experience using RSpec over the last month. I call them the other RSpec methods, as their value becomes apparent after using RSpec for a while. I view their purpose as cleaning up setup code located in before blocks.

#let

Get rid of instance variables using #let. Let memoizes a block:

# before "#let"
  before do
    @valid_customer = Customer.new(:name => "Frank Reynolds")
  end

  it "should be valid" { @valid_customer.should be_valid }

  # with "#let"
  let(:valid_customer) { Customer.new(:name => "Frank Reynolds") } 

  it "should be valid" { valid_customer.should be_valid }

#subject and #specify

The subject specifies the object's behaviour that's being described:

subject { Customer.new(:name => "Frank Reynolds") }

 it "should be valid" { subject.should be_valid }

And it doesn't make sense to describe the behaviour ourselves, since RSpec will generate that for us:

subject { Customer.new(:name => "Frank Reynolds") }

 it { subject.should be_valid }

That doesn't read well, so let's use the alias "#specify":

subject { Customer.new(:name => "Frank Reynolds") }

 specify { subject.should be_valid }

But we can use an implicit subject, meaning we don't need to specify the subject (and we revert back to #it):

subject { Customer.new(:name => "Frank Reynolds") }

 it { should be_valid }

Finally, we can also use an implicit subject based on the object we are describing:

describe Customer do
  it { should_not be_valid }
 end

What are your "other" RSpec methods? Let me know in the comments.

Please note this blog is no longer maintained. Please visit CivilCode Inc - Custom Software Development.