I'm a big noob when it comes to testing or test-based development, so I'm really struggling with testing my code. The biggest reason why such situations ...
I have a model, Photo , which has the fields "place", "city", "state" and "country".
I created a "location" method that can take one argument and will return either a minimal form, or a short form, or the full location of the form. Here's the model code:
def location( form=:full ) usa = country.eql?('US') || country.eql?('United States') country_name = Carmen::country_name( self.country ) if self.state.present? state_name = Carmen::state_name( self.state ) end case [form, usa] when [:min, true] then ( self.city.blank? ? self.place : self.city ) when [:min, false] then ( self.city.blank? ? self.place : self.city ) when [:short, true] then [ ( self.city.blank? ? self.place : self.city ), state_name ].join(', ') when [:short, false] then [ ( self.city.blank? ? self.place : self.city ), country_name ].join(', ') when [:full, true] then [ self.place, self.city, state_name ].delete_if{|a| a.blank? }.join(', ') when [:full, false] then [ self.place, self.city, country_name ].delete_if{|a| a.blank? }.join(', ') else raise "Invalid location format" end end
As you can see, this is pretty clean and eloquent. Now, here is my specification:
describe "location" do before do @us = Photo.new(:place => "Main St.", :city => "Barville", :state => "TX", :country => "US") @uk = Photo.new(:place => "High St.", :city => "Barchester", :country => "GB") @it = Photo.new( :place => "il Commune", :city => "Baria", :state => "AR", :country => "IT" ) end context "minimum form" do it "should return city or place for US Photos" do @us.location(:min).should == "Barville" @us.city = "" @us.location(:min).should == "Main St." end it "should return city or place for Internationals without states" do @uk.location(:min).should == "Barchester" @uk.city = "" @uk.location(:min).should == "High St." end it "should return city or place for Internationals with states" do @it.location(:min).should == "Baria" @it.city = "" @it.location(:min).should == "il Commune" end end context "short form" do it "should return city,state or place,state for US photos" do @us.location(:short).should == "Barville, Texas" @us.city = "" @us.location(:short).should == "Main St., Texas" end it "should return city,country or place,country for Internationals without states" do @uk.location(:short).should == "Barchester, United Kingdom" @uk.city = "" @uk.location(:short).should == "High St., United Kingdom" end it "should return city,country or place,country for Internationals with states" do @it.location(:short).should == "Baria, Italy" @it.city = "" @it.location(:short).should == "il Commune, Italy" end end context "full form" do context "US Photos" do it "should return place, city, state" do @us.location(:full).should == "Main St., Barville, Texas" end it "should return place, state if city is blank" do @us.city = "" @us.location(:full).should == "Main St., Texas" end it "should return city, state if place is blank" do @us.place = "" @us.location(:full).should == "Barville, Texas" end end context "Internationals without states" do it "should return place, city, state" do @uk.location(:full).should == "High St., Barchester, United Kingdom" end it "should return place, state if city is blank" do @uk.city = "" @uk.location(:full).should == "High St., United Kingdom" end it "should return city, state if place is blank" do @uk.place = "" @uk.location(:full).should == "Barchester, United Kingdom" end end end context "Internationals with states" do it "should return place, city, state" do @it.location(:full).should == "il Commune, Baria, Italy" end it "should return place, state if city is blank" do @it.city = "" @it.location(:full).should == "il Commune, Italy" end it "should return city, state if place is blank" do @it.place = "" @it.location(:full).should == "Baria, Italy" end end end
So, 98 lines of test code to test 17 lines of model code. It seems crazy to me. Plus, the time it takes to test it in RSpec is frankly much more than the time it takes to test it on the console.
So, I have two questions:
- Of course, there is a better way to do this. Can anyone suggest refactoring?
- Is this a test code relation for a normal model code, and if so, why is it worth the time?
Thanks!!
- EDIT -
To be clear, I'm most interested in refactoring the test code , not the location method.