Controller Tests fail

Hi all,

I'm hoping someone can help me here I'm trying to carry out functional
testing, my IDE is NetBeans 6.8 and I've found that any tests on
controllers who have to deal with related data are failing.

I've got a controller called business that hold the details of a
business along with its owner which is a user created using authlogic.

In the get_index, and show_business sections of the test I'm getting an
ActionView error because I've changed the related view to display the
related data not the actualy foreign key e.g. it shows 'Graham' not 1

The errors reported are

test_should_get_index(BusinessesControllerTest):
ActionView::TemplateError: undefined method `login' for nil:NilClass
On line #24 of app/views/businesses/index.html.erb

    21: <td><%=h business.country %></td>
    22: <td><%=h business.longitude %></td>
    23: <td><%=h business.lattitude %></td>
    24: <td><%=h business.user.login %></td>
    25: <td><%= link_to 'Show', business %></td>
    26: <td><%= link_to 'Edit', edit_business_path(business) %></td>
    27: <td><%= link_to 'Destroy', business, :confirm => 'Are you
sure?', :method => :delete %></td>

test_should_show_business(BusinessesControllerTest):
ActionView::TemplateError: undefined method `login' for nil:NilClass
On line #38 of app/views/businesses/show.html.erb

    35:
    36: <p>
    37: <b>Business Owner:</b>
    38: <%=h @business.user.login%>
    39: </p>
    40:
    41: <%= link_to 'Edit', edit_business_path(@business) %> |

I am also getting a run time error on the get_new test as it can't save
a record because there is no logged in user.

I've read that these failures are normal because of the changes I made
ocurred after ROR created the test files but not how to resolve the
issues.

Can anyone give me some pointers on this???

Thanks,

Graham

How did you write your Business and User models?
What you are trying to do is as simple as a relation between User and
Business model. And i guess it should be like the following:

class User < AR::B
    has_many :businesses # or
# has_one :business
end

class Business < AR::B
    belong_to :user
end

Now if you have these setup as expected then what about your yml
files? Did you made the exact relationship there? If you have
businesses.yml and users.yml then a business object should have a
user_id which should refer a user id from users.yml

With a proper relation with user_id of businesses table with id of
users table would return a user object if you call business.user and
then you can call whatever method of that user object.
However, could you please explain what is the user.login method doing
here??
As you said

foreign key e.g. it shows 'Graham' not 1

It should be like user.name or user.first_name or something else. But
login method doesnt seem that intuitive or im missing something?

Let me know the status...

Samiron paul
http://samironpaul.blogspot.com/

Samiron Rony wrote:

How did you write your Business and User models?
What you are trying to do is as simple as a relation between User and
Business model. And i guess it should be like the following:

class User < AR::B
    has_many :businesses # or
# has_one :business
end

class Business < AR::B
    belong_to :user
end

Now if you have these setup as expected then what about your yml
files? Did you made the exact relationship there? If you have
businesses.yml and users.yml then a business object should have a
user_id which should refer a user id from users.yml

With a proper relation with user_id of businesses table with id of
users table would return a user object if you call business.user and
then you can call whatever method of that user object.
However, could you please explain what is the user.login method doing
here??
As you said

foreign key e.g. it shows 'Graham' not 1

It should be like user.name or user.first_name or something else. But
login method doesnt seem that intuitive or im missing something?

Let me know the status...

Samiron paul
http://samironpaul.blogspot.com/

Hi Samiron,

Sorry for the delay in replying.

I've setup my business and user models as follows

class Business < ActiveRecord::Base
  belongs_to :user

class User < ActiveRecord::Base
  has_one :business

In relation to the yml files please pardon my ignorance I take it that
its the file in the Fixtures folder if so here they are please note the
user_id I had to add myself.

one:
  id: 1
  name: Graham's Bar
  user_id: 1
  address: 112 O'Connell Street
  province: Dublin 1
  city: Dublin
  country: Ireland
  longitude: 1.5
  lattitude: 1.5

two:
  id: 2
  name: Joe's Bar
  user_id: 2
  address: 12 Grafton Street
  province: Dublin 2
  city: Dublin
  country: Ireland
  longitude: 22.4
  lattitude: 22.5

In relation to the user.login I had to add that to display the users
name not the id field data. The field login is setup by default by
authlogic.

If I'm leaving anything that you need out please let me know.

Graham

Hi Samiron,

After looking at your relpy again I have edited the user and business
yml files to the following.

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

Business
one:
  id: 1
  name: Graham's Bar
  user_id: 1
  address: 112 O'Connell Street
  province: Dublin 1
  city: Dublin
  country: Ireland
  longitude: 1.5
  lattitude: 1.5

two:
  id: 2
  name: Joe's Bar
  user_id: 2
  address: 12 Grafton Street
  province: Dublin 2
  city: Dublin
  country: Ireland
  longitude: 22.4
  lattitude: 22.5

Users

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

one:
  id: 1
  login: Graham
  crypted_password: MyString
  password_salt: MyString
  persistence_token: MyString
  login_count: 1
  last_request_at: 2010-02-24 17:14:15
  last_login_at: 2010-02-24 17:14:15
  current_login_at: 2010-02-24 17:14:15
  last_login_ip: MyString
  current_login_ip: MyString

two:
  id: 2
  login: Joe
  crypted_password: MyString
  password_salt: MyString
  persistence_token: MyString
  login_count: 1
  last_request_at: 2010-02-24 17:14:15
  last_login_at: 2010-02-24 17:14:15
  current_login_at: 2010-02-24 17:14:15
  last_login_ip: MyString
  current_login_ip: MyString

This has resolved two of the earlier errors

test_should_get_index(BusinessesControllerTest):
ActionView::TemplateError: undefined method `login' for nil:NilClass

and
test_should_show_business(BusinessesControllerTest):
ActionView::TemplateError: undefined method `login' for nil:NilClass

But I'm still getting the error on testing creating a new business

test_should_get_new(BusinessesControllerTest):
RuntimeError: Called id for nil, which would mistakenly be 4 -- if you
really wanted the id of nil, use object_id

I'm also getting the following error.
test_should_create_business(BusinessesControllerTest):
"Business.count" didn't change by 1. <3> expected but was <2>.

Thanks for all your help

Graham

Graham Farrell wrote:

Hi all,

I'm hoping someone can help me here I'm trying to carry out functional
testing,

Functional tests and fixtures (which I gather you're using from a later
post) are two Rails features that are best avoided entirely.

Instead of functional tests, use Cucumber features.

Instead of fixtures, use factories.

Your life will be a lot easier.

my IDE is NetBeans 6.8

Bonus tip: lose NetBeans and just use a decent text editor (I like
KomodoEdit). Rails doesn't need or want an IDE.

Best,

Functional tests and fixtures (which I gather you're using from a later
post) are two Rails features that are best avoided entirely.

Page 224 of Agile Web Development with Rails, 3rd Edition by Dave
Thomas, DHH, and Sam Ruby seems to disagree with you entirely.

Instead of functional tests, use Cucumber features.

Instead of fixtures, use factories.

Your life will be a lot easier.

I've tried those and I see no good reason to replace what comes with
Rails and works great already. I wouldn't give you two cents for
Factory Girl, Cucumber, Webrat and the like. They're all just
academic masturbation.

Greg Donald wrote:

Functional tests and fixtures (which I gather you're using from a later
post) are two Rails features that are best avoided entirely.

Page 224 of Agile Web Development with Rails, 3rd Edition by Dave
Thomas, DHH, and Sam Ruby seems to disagree with you entirely.

I'm not surprised, given that DHH co-wrote that book. There are parts
of Rails that he and the core team simply got wrong architecturally.
These are among them.

Instead of functional tests, use Cucumber features.

Instead of fixtures, use factories.

Your life will be a lot easier.

I've tried those and I see no good reason to replace what comes with
Rails and works great already. I wouldn't give you two cents for
Factory Girl, Cucumber, Webrat and the like. They're all just
academic masturbation.

Nope! They're practical tools that improve noticeably on what Rails
already offers. I have used fixtures and controller tests, and I know
that I'm better off now that I've replaced them.

Use what works for you. But don't claim "academic masturbation" in the
face of many of us who know it not to be true.

And with that, I'm done, unless you have specific issues with these
tools that you'd like to discuss. FUD and innuendo don't do much for
me.

--
Greg Donald
destiney.com | gregdonald.com

Best,

That's been my experience when using them. There's no reason to to
replace what's already there and already works great. Two others help
write the book. I would trust the three of those guys before anyone
who endorses Cucumber, any day of the week.

I am using what works for me. Seems they are too.

I'm not a fan of dogmatism on either side. A few observations though:

1) I own every edition of AWDWR, including the latest version
covering Rails 3. Each edition is an evolution of its predecessor. It
started with test/unit and fixtures since that's what came with Ruby
and was baked into rails. Although alternatives have appeared, the
book has tended to stay there, probably because a) it's talking about
what comes with rails, and b) it's easier not to rewrite sections when
you don't have to. There are also pedagogical concerns. AWDWR is
primarily an introduction to rails. Just like they teach physics in
high school without recourse to calculus, doesn't mean that calculus
isn't a very useful tool when you really start to practice Physics,
some advanced topics are best left to later courses.

2) Rails 3 has refactored rails so that test/unit isn't closely
coupled. If you install the rspec-rails and cucumber plugins, for
example the rails3 generators will automatically produce rspec specs
and cucumber features. Since the 4th edition of AWDWR is in an early
beta form, I don't know how much Sam will cover this. Again, there's
a certain amount of inertia. For one thing he has made and effort to
bring testing earlier in the depot example, which I like. However he
hasn't changed the flow to use test driven design, which is and should
be standard practice for rails developers whether they are using
test/unit, rspec, shoulda ..., I understand that just breaking up the
testing chapter and reshuffling the chapters. It's better but it still
comes across as fostering code first then test, which I doubt the
authors fully endorse.

3) Fixtures. There are lots of experience Rails developers who have
come to the conclusion that fixtures really s*ck. Hence all the
fixture replacement plugins. In my experience, these days fixture
replacements tend to be used much more than the built-in rails
fixtures in real-world rails projects, not that there's much of
consensus on which one is best. If fixtures work for you find, if
not...

4) RSpec and Cucumber are seen as very powerful tools by a wide range
of Rubyists and Rails app developers. Far from spilling our
intellectual seeds on the ground, as your colorful characterization
would have it, we are being very prolific, thank you!

5) I would argue that the fact that Dave Thomas is the publisher of
"The RSpec Book", which really should be called the RSpec and Cucumber
book, constitutes an endorsement of RSspec and Cucumber.

But then as they say in Rome, de gustibus non est disputandum! Use
your intellectual seeds as you will.

And still the default for Rails is something else.