As I've used RSpec more, I've grown less and less fond of fixtures for Rails testing. In everything except model specs, I use mocks for the models and don't touch the database. Sometimes, however, I still want to test the database interaction in my model specs.
I'm working on a project that has plenty of existing test cases (both RSpec and Test::Unit) that depend on fixtures. As much as I'd like to eliminate that dependency, the show must go on, and I need to keep writing specs for new functionality. When I create a new model spec that does test database interaction, I want the database to be in a known state at the start of each spec - and the easiest known state to work with is empty, so today I whipped up the following snippet to empty out relevant tables at the beginning of each spec run:
# Wean ourselves off of fixtures
# Call this within the description (e.g., after the describe block) to remove everything from the associated class or table
module Spec
module DSL
module BehaviourCallbacks
def reset_tables(*tables)
callback = lambda do
tables.each do |table|
ActiveRecord::Base.connection.delete("DELETE FROM #{table.to_s.tableize}")
end
end
before_each_parts << callback
end
end
end
end
If you drop this into your spec_helper.rb, then, in your specs, you can do the following:
require File.dirname(__FILE__) + '/../spec_helper'
describe BookOrders, "A newly created BookOrder" do
reset_tables :book_orders, :books, :customer
before(:each) do
# setup some stuff
end
it "should require a customer" do
# blah blah
end
# and so on
end