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

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.