I have an address model with country_id and province_id fields There is also a full_address method that returns an address that is in a format that the google maps api will be able to return a long-lat coords. Within the full_address method there is a call to obtain the province/state and country name. --------- def full_address ... full_address = [city, self.province.name, self.country.name].join(",").chomp(",") .. end When I run this in the console it works fine>> a = Address.new=> #<Address:0x24c6420 @new_record=true, @attributes={"city"=>nil, "latitude"=>nil, "region_code"=>nil, "province_id"=>nil, "country_id"=>nil, "location_type"=>nil, "location_id"=>nil, "address_1"=>nil, "address_2"=>nil, "longitude"=>nil, "address_3"=>nil, "address_4"=>nil}>>> a.country_id = 1=> 1>> a.country.name=> "Canada">> a.province_id = 1=> 1>> a.full_address=> ",,Alberta,Canada" but when the specs are run I get errors saying that the country and province object properties are null 11) NoMethodError in ''Address additional properties should ensure spacing between the st/ave on the address'' You have a nil object when you didn''t expect it! The error occurred while evaluating nil.name /Users/chris/Documents/Projects/Rails/MyProject/trunk/config/../app/models/address.rb:25:in `full_address'' ./spec/models/address_spec.rb:66: script/spec:4: Here is one of the tests that fail: describe Address, "additional properties" do before(:each) do @address = Address.new(valid_params) end def valid_params { :country_id => 1, :province_id => 1, :region_code => "T5Z3J4", :address_1 => "13245-56 st", :address_2 => "NW", :city => "Edmonton" } end it "should return the full address format" do @address.country_id.should == 1 #this passes @address.province_id.should == 1 #this passes @address.province.name.should == "Alberta" #this fails @address.country.name.should == "Canada" #this fails @address.full_address.should == "13245-56 st NW,Edmonton,Alberta,Canada" #and this fails if you remove the ones above end class Address < ActiveRecord::Base belongs_to :province belongs_to :country class Country < ActiveRecord::Base has_one :address If I wasn''t able to make it happen in the console, it would make more sense, but seeing as I can I am totally lost. Thanks for the help -- Posted via http://www.ruby-forum.com/.
Hans de Graaff
2007-Nov-07 06:49 UTC
[rspec-users] Unexplainable failure...at least for me
On Wed, 2007-11-07 at 06:39 +0100, Chris Olsen wrote:> but when the specs are run I get errors saying that the country and > province object properties are null > 11) > NoMethodError in ''Address additional properties should ensure spacing > between the st/ave on the address'' > You have a nil object when you didn''t expect it! > The error occurred while evaluating nil.name > /Users/chris/Documents/Projects/Rails/MyProject/trunk/config/../app/models/address.rb:25:in > `full_address'' > ./spec/models/address_spec.rb:66: > script/spec:4: > > Here is one of the tests that fail: > describe Address, "additional properties" do > > before(:each) do > @address = Address.new(valid_params) > end > > def valid_params > { > :country_id => 1, > :province_id => 1, > :region_code => "T5Z3J4", > :address_1 => "13245-56 st", > :address_2 => "NW", > :city => "Edmonton" > } > endThe question is where this country and province with id 1 are defined. I don''t see anything in your spec to indicate that they are ever created. If you are using fixtures then you''ll need to explicitly include them. Otherwise they may or may not still be loaded in the test database and at best you''ll get a clear failure and at worst inconsistent results. describe Address do fixtures :provinces, countries before ... etc Kind regards, Hans -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://rubyforge.org/pipermail/rspec-users/attachments/20071107/3f85bb78/attachment.bin
That is the problem, which is clear now that I tested it with the script/console in test mode rather than development. So now the question is, why does the data not exist in the test database. The country and province data inserts exist within the migration files, ex for countries: class CreateCountries < ActiveRecord::Migration def self.up create_table :countries do |t| t.column :country_id, :integer t.column :name2, :string, :limit => 2 t.column :name3, :string, :limit => 3 t.column :name, :string t.column :district_name, :string t.column :code_name, :string t.column :strength, :integer end country_data = [ [124, ''CA'', ''CAN'', ''Canada'', ''Province'', ''Postal Code'', 100], [840, ''US'', ''USA'', ''United States'', ''State'', ''ZipCode'', 50], #along with many other countries ].each do |c| insert_params = { :country_id => c[0], :name2 => c[1], :name3 => c[2], :name => c[3], :district_name => c[4], :code_name => c[5], :strength => c[6] } Country.create(insert_params) end end Thanks for the help.> The question is where this country and province with id 1 are defined. I > don''t see anything in your spec to indicate that they are ever created. > If you are using fixtures then you''ll need to explicitly include them. > Otherwise they may or may not still be loaded in the test database and > at best you''ll get a clear failure and at worst inconsistent results. > > describe Address do > fixtures :provinces, countries > > before ... etc > > Kind regards, > > Hans-- Posted via http://www.ruby-forum.com/.
Chris Olsen wrote:> That is the problem, which is clear now that I tested it with the > script/console in test mode rather than development. > > So now the question is, why does the data not exist in the test > database. The country and province data inserts exist within the > migration files, ex for countries: > > class CreateCountries < ActiveRecord::Migration > def self.up > create_table :countries do |t| > t.column :country_id, :integer > t.column :name2, :string, :limit => 2 > t.column :name3, :string, :limit => 3 > t.column :name, :string > t.column :district_name, :string > t.column :code_name, :string > t.column :strength, :integer > end > > country_data = [ > [124, ''CA'', ''CAN'', ''Canada'', ''Province'', ''Postal Code'', 100], > [840, ''US'', ''USA'', ''United States'', ''State'', ''ZipCode'', 50], > #along with many other countries > ].each do |c| > > insert_params = { > :country_id => c[0], > :name2 => c[1], > :name3 => c[2], > :name => c[3], > :district_name => c[4], > :code_name => c[5], > :strength => c[6] > } > > Country.create(insert_params) > end > end > > Thanks for the help.I should mention that the test database is cloned properly with the script: task :reset_databases do system "mysqladmin -u root drop MyDB_development" system "mysqladmin -u root drop MyDB_test" system "mysqladmin -u root create MyDB_development" system "mysqladmin -u root create MyDB_test" system "rake db:migrate" system "rake db:test:clone_structure" end script/console test>> Country.find(:all)=> [] -- Posted via http://www.ruby-forum.com/.
On 7 Nov 2007, at 14:49, Chris Olsen wrote:> So now the question is, why does the data not exist in the test > database. The country and province data inserts exist within the > migration files, ex for countries:As someone who knows literally nothing about how this all works, I still feel confident enough to guess that RSpec doesn''t actually run any migrations, but rather just clones the schema of the existing development database -- so you get something that looks the same but contains no data. As the previous poster mentioned, you need to put the data into fixtures and include them; see http://rspec.rubyforge.org/documentation/rails/writing/models.html for examples. Cheers, -Tom