Unexplainable failure...at least for me

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

On Wed, 2007-11-07 at 06:39 +0100, Chris O. wrote:

script/spec:4:
:country_id => 1,
:province_id => 1,
:region_code => “T5Z3J4”,
:address_1 => “13245-56 st”,
:address_2 => “NW”,
:city => “Edmonton”
}
end

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

Chris O. 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)
=> []

On 7 Nov 2007, at 14:49, Chris O. 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

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

That would make sense.

Thanks for the help.