Testing has_many, and habtm relationships with RSpec is now DRY.
Based on Ben Mabey’s idea testing model relationships reduces to calling a simple method from a shared RSpec helper.
In my previous post spec_shared_model.rb was designed to be a helper holding my shared specs, and it was included in user_spec.rb. Now I’ve added two general purpose functions to this helper: one will check has_one relationships, the other has_many relationships. The parameters are the model and the relationship, so it can be used to check belongs_to and belongs_to_many relationships too.
Taking the first listing from the previous example,
User relations : - has one or more Roles - has one or more Orgcharts - belongs to one or more Orgcharts - has one or more Executions - has one or more Tasks through Participants - on deleting User also the Participants will be removed
will become:
User relations - has one Role - has many Roles - has one Orgchart - has many Orgcharts - belongs to one Orgchart - belongs to many Orgcharts - has one Execution - has many Executions - has one or more Tasks through Participants - on deleting User also the Participants will be removed
where each assertion is backed up by real tests. To achieve this, you’ll have to add the following code in spec_shared_model.rb:
describe "Relationships", :shared => true do def self.it_has_one(model, relation, output=nil) it "#{output}" do model << relation model.should_not be_empty end end def self.it_has_more(model, relation, output=nil) it "#{output}" do model << relation model << relation model.size.should == 2 end end end
and in user_spec.rb replace
describe "relations" do
block with
it_should_behave_like "Relationships" it_has_one User.new.roles, Role.new, "has one Role" it_has_more User.new.roles, Role.new, "has many Roles" it_has_one User.new.orgcharts, Orgchart.new, "has one Orgchart" it_has_more User.new.orgcharts, Orgchart.new, "has many Orgcharts" it_has_one Orgchart.new.users, User.new, "belongs to one Orgchart" it_has_more Orgchart.new.users, User.new, "belongs to many Orgcharts" it_has_one User.new.executions, Execution.new, "has one Execution" it_has_more User.new.executions, Execution.new, "has many Executions"


