Leaving the beaten track with RSpec
Posted by Craig Ambrose on December 05, 2007 at 07:16 AM
I’ve spent today learning RSpec. To get my head around it, I decided to spec a controller action which I’d already written and tested with Test::Unit. It’s a pretty basic CRUD action, requiring login and ownership of the record.
Here’s the spec and test code side by side:
I’m not sure which one was easier. The RSpec version is certainly a lot longer. Having said that, the Test::Unit one uses fixtures, which aren’t included in the dump.
In RSpec’s favour, is that the specifications run much faster (as they don’t use the database), and they also better decouple the controller from the model, as it’s a more true “unit” test. Having said that, I believe that the RSpec version might actually be a little bit more fragile, as it would fail if the code under test changed to perform the same operation using different methods (such as calling ActiveRecord create, instead of new and save).
Also, some of the things I specified in terms of expectations are actually order dependent, which is not captured in my specs, so if I deliberately messed up the order of some of the code, I might get false positives with my specifications.
For the record, here’s the code under test.
before_filter :login_required, :only => [:new, :create, :edit, :update]
before_filter :load_user
before_filter :current_user_can_edit_user, :only => [:new, :create, :edit, :update]
before_filter :load_user_base_tabs
def create
@photo_set = PhotoSet.new(params[:photo_set])
@photo_set.profile = @profile
success = @photo_set.save respond_to do |format|
format.html do
if success
redirect_to user_photo_set_path(@user, @photo_set)
else
render :action => 'new'
end
end
end
end
