RSPEC and RoR undefined method for hash when running model tests

Within my project, I have a number of models that have additional
methods
within them other than those provided by active record.

as an example (to keep it short and sweet)

class foo < ActiveRecod::Base

def status
“New Record”
end

def reset
“Reset”
end

end

in my spec file I have

require ‘spec_helper’

describe Foo do

before(:each) do
@foo = Foo.new()
end

it “should have a status of New Record”
@foo.status.should == “New Record”
end

it “should have a status of Reset after reset”
@foo.reset.should == “Reset”
end
end

however, when I run rake spec I get
NoMethodError in ‘Foo should have a status of New Record’
undefined method ‘status’ for #<Hash…>

and an equivalent one for the other method.

I am sure that this is something fundamental in my understanding, but
I’m
scuppered. I have spent the best part of a day trying to resolve this.

so,

  1. Why are my methods undefined, when they are there (I can create the
    object via script/console and call the status and reset methods and see
    them
    work)
  2. What is the best way of resolving the issue

Thanks

On 14 Dec 2009, at 20:36, Matt Riches wrote:

  1. Why are my methods undefined, when they are there (I can create the object via script/console and call the status and reset methods and see them work)
  2. What is the best way of resolving the issue

You’d be much better off using pastie.org to show us the real code
that’s having the problem, because your example contains all sorts of
omissions and typos (which is likely to be the sort of thing that causes
your problem!) and it’s impossible to tell how much of it is wrong in
the original code versus how much was introduced by you rewriting it as
an example.

Cheers,
-Tom

Looks like you forgot to put “do” at the end of your specs. I do that
all the time;

it “should have a status of New Record”

Should be

it “should have a status of New Record” do

HTH

David

2009/12/14 Tom S. [email protected]:

This should have been the giveaway

undefined method ‘status’ for #<Hash…>

In your before you’re assigning @address to the parameters, not to a new
address
@address = {:foo => ‘bar’}
instead of
@address = Address.new({:foo => ‘bar’})

-V

On 14 Dec 2009, at 21:28, Matt Riches wrote:

@address.reset
@address.status.should == :Address::DELETED

end
end

The problem is that you’re setting @address to a hash, not an instance
of Address. Did you mean @address = Address.new :business_name => …?

Cheers,
-Tom

I am still learning, and its been along and frustrating day, but thanks
!

Sometimes a fresh (more experienced pair of eyes) can spot the
blindingly
obvious :slight_smile:

ok, one more quick question, and its slightly more general and then Im
going
home for the day.

When I run my tests now I get a series of lines
warning: already initialised constant JUST_REGISTERED
warning: already initialised constant DELETED

etc.

as its only a warning I am not too bothered, but ideally I’d like to
stop it
if I can. Is this an artefact of me creating constants in the class,
then it
being called before(:each) ? Is there some way of supressing the
warnings,
or making the constants only get assigned once? (Maybe another class
that
just implements the constants?)

Regards

Matt

2009/12/14 Vishu R. [email protected]

Fair point, thought you could also assume that the omissions are down to
my
newness at RSpec and RoR :slight_smile:

The whole of the code is rather large, I am being asked to retrofit
rspec
onto the code base as things are changed, so I am only showing what I
think
are the relevent things…

Code Section

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

class Address < ActiveRecord::Base

#Status Codes as Constants
JUST_REGISTERED = 0
DELETED = 1
DECLINED = 2
APPROVED = 3

def status
DELETED
end

def reset
#We don’t actually delete the record
#Instead a status field is set
#And all the data is blanked for data protection reasons

self.status = DELETED
self.business_name = ''
self.first_line = ''
self.second_line = ''
self.town = ''
self.county = ''
self.postcode = ''
#MR - added in the following fields
self.lat = 0.0
self.lng = 0.0
self.route_id = 0
self.save

end
#… other code elided
end


RSpec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

require ‘spec_helper’

describe Address do
#Test Fixture - Before Each test Create a Standard Bread with the
following attributes and properties
before(:each) do
@address = {
:business_name => ‘business’, :first_line => ‘10, This Street’,
:second_line=> ‘erewhon’, :town=> ‘town’, :county=>‘county’,
:postcode =>‘AB12 3CD’, :user_id => 1, :lat=>1.01, :lng=>2.02,
:status=>Address::JUST_REGISTERED, :route_id=>1
}
end

it “should have a status of deleted after reset” do

@address.reset

@address.status.should == :Address::DELETED

end

end

Thanks David as well, but Tom was right, it was my typing that caused
that
issue.

Regards

Matt

2009/12/14 Tom S. [email protected]

Yup, I did.

Thanks all. (unless anyone has any comments on the constants question I
just
asked in a previous post?)

Regards

Matt

2009/12/14 Tom S. [email protected]