[rspec-users] RSPEC and RoR undefined method for hash when running model tests

43 views
Skip to first unread message

Matt Riches

unread,
Dec 14, 2009, 3:36:48 PM12/14/09
to rspec...@rubyforge.org
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



Tom Stuart

unread,
Dec 14, 2009, 3:54:26 PM12/14/09
to rspec-users
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
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

David Salgado

unread,
Dec 14, 2009, 4:04:09 PM12/14/09
to rspec-users
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 Stuart <t...@experthuman.com>:

Matt Riches

unread,
Dec 14, 2009, 4:28:42 PM12/14/09
to rspec-users
Fair point, thought you could also assume that the omissions are down to my newness at RSpec and RoR :-)

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 Stuart <t...@experthuman.com>

Vishu Ramanathan

unread,
Dec 14, 2009, 4:33:06 PM12/14/09
to rspec-users
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

--
Vishu Ramanathan
co-founder thinklink llc 312.436.1627
new homepage! ---> thinklinkllc.com
mocklinkr.com makes web mockups come to life
thinklinkr.com is the web-based collaborative outliner

Tom Stuart

unread,
Dec 14, 2009, 4:39:22 PM12/14/09
to rspec-users
On 14 Dec 2009, at 21:28, Matt Riches wrote:
> 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

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

Matt Riches

unread,
Dec 14, 2009, 4:48:49 PM12/14/09
to rspec-users
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 :)

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 Ramanathan <vi...@thinklinkr.com>

Matt Riches

unread,
Dec 14, 2009, 4:50:04 PM12/14/09
to rspec-users
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 Stuart <t...@experthuman.com>
On 14 Dec 2009, at 21:28, Matt Riches wrote:
Reply all
Reply to author
Forward
0 new messages