RSpec
     documentation

http://relishapp.com/rspec
components
   RSpec Core

RSpec Expectations

  RSpec Mocks

   RSpec Rails
run specs
rake spec

rake spec:models

rspec spec/models/order_spec.rb
rspec spec/models/order_spec.rb:19
"be" matchers
describe 0 do
  it { subject.zero?.should == true }

  # vs.

  it { should be_zero } # 0.zero? == true
end
have(n).items matcher
collection.should have(x).items
collection.should have_at_least(x).items
collection.should have_at_most(x).items

it { should have(5).line_items }
subject
implicit subject
describe Comment do
  subject { Comment.new }
end
explicit subject
describe Order do
  subject { Factory.build(:order) }
end
implicit receiver
it { subject.should be_valid }

# vs.

it { should be_valid }
its
its(:status_name) { should == :draft }

its('line_items.count') { should == 5 }
let
before do
  @order = Factory.create(:shipped_order)
end

# vs.

let(:order) do
  Factory.create(:shipped_order)
end
context vs. describe
   alias :context :describe

   describe is for methods

   context is for contexts
class & instance methods
describe '#title' do # instance method
  ...
end

describe '.title' do # class method
  ...
end
context
context 'when quantity is negative' do
  before { subject.quantity = -1 }

  ...

end
model validations
it { should be_invalid }

its(:errors) { should be_present }
it { should have(1).errors_on(:quantity) }
shoulda-matchers
it 'should validate email and quantity' do
  subject.email = 'test@example.com'
  subject.quantity = -1
  subject.valid?
  should have(:no).errors_on(:email)
  should have_at_least(1).error_on(:quantity)
end

# vs.
it { should allow_value('test@example.com').for(:email) }

it { should_not allow_value(-1).for(:quantity) }
mocks
fake objects and methods

  don't touch database

      faster specs
rails model mocks
mock_model is a test double that acts like an
              ActiveModel

     stub_model is a instance of a real
 ActiveModel with some methods stubbed
using mocks
let(:email_template) do
  stub_model(EmailTemplate,
             :name => 'test_email', ...)
end

before do
  ...
  EmailTemplate.stub(:find_by_name).
    with('test_email').
    and_return(email_template)
end
message expectation
def should_deliver_mail(method)
  Mailer.should_receive(method).
    with(subject).
    and_return(double(:deliver => nil))
end
questions?

Rspec