I have the following to remove the spaces on a specific attribute.
#before_validation :strip_whitespace
protected
  def strip_whitespace
    self.title = self.title.strip
  end
And I want to test it. For now, I've tried:
it "shouldn't create a new part with title beggining with space" do
   @part = Part.new(@attr.merge(:title => " Test"))
   @part.title.should.eql?("Test")
end
What am I missing?
Validations won't run until the object is saved, or you invoke valid? manually.  Your before_validation callback isn't being run in your current example because your validations are never checked.  In your test I would suggest that you run @part.valid? before checking that the title is changed to what you expect it to be.
class Part < ActiveRecord::Base
  before_validation :strip_whitespace
protected
  def strip_whitespace
    self.title = self.title.strip
  end
end
require 'spec_helper'
describe Part do
  it "should remove extra space when validated" do
    part = Part.new(:title => " Test")
    part.valid?
    part.title.should == "Test"
  end
end
This will pass when the validation is included, and fails when the validation is commented out.
referring to @danivovich example
class Part < ActiveRecord::Base
  before_validation :strip_whitespace
protected
  def strip_whitespace
    self.title = self.title.strip
  end
end
the proper way to write the spec is to separately write spec on strip_whitespace method and then just check if model class have callback set on it, like this:.
describe Part do
  let(:record){ described_class.new }
  it{ described_class._validation_callbacks.select{|cb| cb.kind.eql?(:before)}.collect(&:filter).should include(:strip_whitespace) }
  #private methods
  describe :strip_whitespace do
    subject{ record.send(:strip_whitespace)} # I'm using send() because calling private method
    before{  record.stub(:title).and_return('    foo    ')
    it "should strip white spaces" do
      subject.should eq 'foo'
      # or even shorter
      should eq 'foo'
    end
  end
end
if you need to skip callback behavior in some scenarios use
before{ Part.skip_callback(:validation, :before, :strip_whitespace)}
before{ Part.set_callback( :validation, :before, :strip_whitespace)}
Update 20.01.2013
BTW I wrote a gem with RSpec matchers to test this https://github.com/equivalent/shoulda-matchers-callbacks
In general I don't recommend callback at all. They are fine for example in this question, however once you do more complicated stuff like:
After create->
...then you should create custom service object to deal with this and test them separately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With