Using RSpec 2.6 / Rails 3.1 / Postgres:
I am writing a supporting module (in my lib/) that any AR model can include. I'd like to write spec for this module. It needs to be included by an AR::Base model, because it loads associations when included and relies on some AR methods, but i don't want to use my existing model when writing rspec for this module.
I would just like to create an arbitrary AR model, but obviously it would not have a table associated in the database and AR is dying. Here's kindda what I want to do:
class SomeRandomModel < ActiveRecord::Base
include MyModule
# simulate DB attributes that MyModule would be using
attr_accessor :foo, :bar, :baz
end
describe SomeRandomModel do
it '#some_method_in_my_module' do
srm = SomeRandomModel.new(:foo => 1)
srm.some_method_in_my_module.should eq(something)
end
end
Of course, i get some error in postgres about the relation not existing.
Thanks for your help!
There is an alternative way to solve this problem using rpsecs shared_examples_for
, I mention few tricks in the code snippet but for more info see this relishapp-rspec-guide.
With this you can test your module in any of the classes which include it. So you really are testing what you use in your application.
Let's see an example:
# Lets assume a Movable module
module Movable
def self.movable_class?
true
end
def has_feets?
true
end
end
# Include Movable into Person and Animal
class Person < ActiveRecord::Base
include Movable
end
class Animal < ActiveRecord::Base
include Movable
end
Now lets create spec for our module: movable_spec.rb
shared_examples_for Movable do
context 'with an instance' do
before(:each) do
# described_class points on the class, if you need an instance of it:
@obj = described_class.new
# or you can use a parameter see below Animal test
@obj = obj if obj.present?
end
it 'should have feets' do
@obj.has_feets?.should be_true
end
end
context 'class methods' do
it 'should be a movable class' do
described_class.movable_class?.should be_true
end
end
end
# Now list every model in your app to test them properly
describe Person do
it_behaves_like Movable
end
describe Animal do
it_behaves_like Movable do
let(:obj) { Animal.new({ :name => 'capybara' }) }
end
end
I am facing a similar problem, and after much googling I have settled on just setting up and tearing down tables in my RSpec tests. Here's the snippet I've been using:
describe "stuff you are testing do" do
before :all do
m = ActiveRecord::Migration.new
m.verbose = false
m.create_table :random_class do |t|
t.string :field_1
t.integer :field_2
end
end
after :all do
m = ActiveRecord::Migration.new
m.verbose = false
m.drop_table :random_class
end
class RandomClass < ActiveRecord::Base
attr_accessible :field_1, :field_2
end
# Your regular RSpec before(:each) blocks and tests
# ...
# e.g.
it "should be able to use RandomClass" do
rc = RandomClass.create! :field_1 => "hello", :field_2 => 5
rc.field_1.should == "hello"
rc.field_2.should == 5
end
end
I'm not enamored of this solution, but it works. Hope that's helpful for someone! Either that or inspires them to post the best way to accomplish this.
:)
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