Thanks David, this was driving me crazy. In my opinion, I think will
be a great idea to add a new matcher to rspec-rails to do this kind of
comparison better than overriding == , and have total control of what
you want to test in each case. Anyways, thanks for helping me on this.

On Jul 17, 9:41 am, David Chelimsky <dchelim...@gmail.com> wrote:
> On Jul 17, 2010, at 8:09 AM, David Chelimsky wrote:
>
>
>
>
>
>
>
> > On Jul 17, 2010, at 3:29 AM, Daniel Salmeron Amselem wrote:
>
> >> Today I've been writing some tests for a new rails 3 app, but after
> >> reading the doc fromhttp://rdoc.info/projects/rspec/rspec-expectations,
> >> I still can't understand why the test doesn't work. My setup is:
>
> >> rvm 0.1.41
> >> ruby 1.9.2dev (2010-07-11 revision 28618) [x86_64-darwin10.4.0] ->
> >> ruby 1.9.2-rc2
> >> rspec 2.0.0.beta.17
> >> rspec-rails 2.0.0.beta.17
> >> devise 1.1.rc2
>
> >> This is the test for the controller:
>
> >> require 'spec_helper'
>
> >> describe PeopleController do
>
> >> describe "routes" do
> >>   it "should route to GET people#new" do
> >>     {:get => "/people/new"}.should route_to(:controller =>
> >> "people", :action => "new")
> >>   end
> >> end
>
> >> describe "Methods" do
>
> >>   before :each do
> >>     @member = Factory(:member)
> >>     sign_in @member
> >>     @person = @member.build_person
> >>   end
>
> >>   it "should render form for a new person on GET people#new" do
> >>     @member.should_receive(:build_person).and_return(@person)
>
> >>     get :new
>
> >>     assigns[:person].should eql(@person)
> >>     response.should be_success
> >>     response.should render_template("new")
> >>   end
> >> end
>
> >> end
>
> >> And the controller:
>
> >> class PeopleController < ApplicationController
> >> before_filter :authenticate_member!
>
> >> def new
> >>   @person = current_member.build_person
> >> end
>
> >> end
>
> >> When running the test I get:
>
> >> .F.................
>
> >> 1) PeopleController Methods should render form for a new person on GET
> >> people#new
> >>   Failure/Error: assigns[:person].should eql(@person)
>
> >>   expected #<Person id: nil, first_name: nil, last_name: nil,
> >> gender: nil, university: nil, year: nil, email: nil, phone: nil,
> >> house: nil, user_account_id: 126, user_account_type: "Member",
> >> home_town: nil, bio: nil, current_location: nil, high_school: nil,
> >> undergrad: nil, profession: nil, concentration: nil, created_at: nil,
> >> updated_at: nil>
> >>        got #<Person id: nil, first_name: nil, last_name: nil,
> >> gender: nil, university: nil, year: nil, email: nil, phone: nil,
> >> house: nil, user_account_id: 126, user_account_type: "Member",
> >> home_town: nil, bio: nil, current_location: nil, high_school: nil,
> >> undergrad: nil, profession: nil, concentration: nil, created_at: nil,
> >> updated_at: nil>
>
> > Here's how ActiveRecord defines == (to which it delegates from eql?)
>
> >http://github.com/rails/rails/blob/c6e20586372743ce200449bf0ac21aed04...
>
> > It returns false if the record has no id (!comparison_object.new_record?), 
> > even if all of the other attributes match. In order to get this to pass you 
> > have to actually save the object so it has an id, not just build it.
>
> > I discussed this with Rails core members a year or two ago and while they 
> > agreed this would make testing easier, there were two motivating arguments 
> > not to change it: a) conceptually, id-less records are not necessarily the 
> > same entity (this one is a bit fuzzy to me) and b) it's a risky change 
> > given the amount of rails code in existence.
>
> > The other thing you can do is skip the stubbing and just say:
>
> >  assigns(:person).should be_a_new(Person)
>
> > You could also write a custom matcher - something like 
> > match_new_record(other) that compares all of the attributes. Maybe it's 
> > have_same_attributes_as:
>
> >  assigns(:person).should have_same_attributes_as(@person)
>
> > I'd consider adding that to rspec-rails. Might be good to have a matcher 
> > with docs that explain all this to help avoid this sort of confusion in the 
> > future.
>
> Another option would be to add something like this:
>
> RSpec.configure do |c|
>   c.treat_new_active_record_objects_as_equal
> end
>
> ... and have that override ==(other) on ActiveRecord::Base. It's invasive, 
> but you have to take an action to do the override.
>
> WDYT?
>
>
>
>
>
>
>
> > WDYT?,
> > David
>
> >>   (compared using eql?)
> >>   # ./spec/controllers/people_controller_spec.rb:24:in `block (3
> >> levels) in <top (required)>'
>
> >> Finished in 2.29 seconds
> >> 19 examples, 1 failure
>
> >> The error with the full backtrace here:http://gist.github.com/479362
>
> >> Which doesn't seem to make sense. Any ideas?
>
> >> Thanks.
> >> _______________________________________________
> >> rspec-users mailing list
> >> rspec-us...@rubyforge.org
> >>http://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> rspec-us...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to