Sergey Rogachev
2009-Oct-16 12:21 UTC
[rspec-users] How to write a correct RSpec for Polymorphic Association
I don''t know what is need to set in the variable ADDRESSES: Organization.stub!(:find_by_id).with("100").and_return(mock_organization(:id => "100", :addresses => ??? )) Somebody help me. Any ideas? I tried to find the solution of problem but I can''t. --- rspec - controllers def mock_organization(stubs={}) @parent_object ||= mock_model(Organization, stubs) end it "assigns a newly created address as @address" do Organization.stub!(:find_by_id).with("100").and_return( mock_organization(:id => "100", :addresses => ??? )) <<!--- here @parent_object.stub(:addresses).stub(:new).with({:these => ''params''}) post :create, :address => {:these => ''params''}, :organization_id => @parent_object.id assigns[:address].should equal(mock_address) end ---- models ---- class Organization < ActiveRecord::Base has_many :addresses, :as => :addressable end class Address < ActiveRecord::Base belongs_to :addressable, :polymorphic => true end ----- controllers ----- class AddressesController < ApplicationController before_filter :load_parent_object def create @address = @parent_object.addresses.new(params[:address]) respond_to do |format| if @address.save flash[:notice] = ''Address was successfully created.'' format.html { redirect_to(@parent_object) } format.xml { render :xml => @address, :status => :created, :location => @address } else format.html { render :action => "new" } format.xml { render :xml => @address.errors, :status => :unprocessable_entity } end end end private def load_parent_object if params[:organization_id] @parent_object = Organization.find_by_id(params[:organization_id]) end end end -- Posted via http://www.ruby-forum.com/.
David Chelimsky
2009-Oct-17 17:24 UTC
[rspec-users] How to write a correct RSpec for Polymorphic Association
On Fri, Oct 16, 2009 at 7:21 AM, Sergey Rogachev <lists at ruby-forum.com> wrote:> I don''t know what is need to set in the variable ADDRESSES: > Organization.stub!(:find_by_id).with("100").and_return(mock_organization(:id > => "100", :addresses => ??? )) > > Somebody help me. Any ideas? I tried to find the solution of problem but > I can''t. > > --- rspec - controllers > def mock_organization(stubs={}) > ?@parent_object ||= mock_model(Organization, stubs) > end > > it "assigns a newly created address as @address" do > ?Organization.stub!(:find_by_id).with("100").and_return( > ? ? ? mock_organization(:id => "100", :addresses => ??? )) <<!--- here > ?@parent_object.stub(:addresses).stub(:new).with({:these => ''params''}) > > ?post :create, :address => {:these => ''params''}, :organization_id => > @parent_object.id > ?assigns[:address].should equal(mock_address) > end > > ---- models ---- > class Organization < ActiveRecord::Base > ?has_many :addresses, :as => :addressable > end > > class Address < ActiveRecord::Base > ?belongs_to :addressable, :polymorphic => true > end > > ----- controllers ----- > class AddressesController < ApplicationController > ?before_filter :load_parent_object > > ?def create > ? ?@address = @parent_object.addresses.new(params[:address]) > > ? ?respond_to do |format| > ? ? ?if @address.save > ? ? ? ?flash[:notice] = ''Address was successfully created.'' > ? ? ? ?format.html { redirect_to(@parent_object) } > ? ? ? ?format.xml ?{ render :xml => @address, :status => :created, > :location => @address } > ? ? ?else > ? ? ? ?format.html { render :action => "new" } > ? ? ? ?format.xml ?{ render :xml => @address.errors, :status => > :unprocessable_entity } > ? ? ?end > ? ?end > ?end > > ?private > > ?def load_parent_object > ? ?if params[:organization_id] > ? ? ?@parent_object = Organization.find_by_id(params[:organization_id]) > ? ?end > ?end > > endHi Sergey, This is a great example of why it''s helpful to write the examples first. There is no need for this controller to know anything about organizations - that can be handled by the model, where the association is defined. Here''s how I might have done this: it "assigns a newly created address as @address" do address = stub_model(Address) Address.stub(:new). with({:these => ''params''}). and_return(address) post :create, :address => {:these => ''params''} assigns[:address].should equal(address) end class AddressesController < ApplicationController def create @address = Address.new(params[:address]) respond_to do |format| if @address.save flash[:notice] = ''Address was successfully created.'' format.html { redirect_to(@address.addressable) } format.xml { render :xml => @address, :status => :created, :location => @address } else format.html { render :action => "new" } format.xml { render :xml => @address.errors, :status => :unprocessable_entity } end end end end Now the post to the create action can include :organization_id within params[:address] instead of as a separate hash key, and all is well. That said, the following _should_ work w/ your current design: it "assigns a newly created address as @address" do address = mock(''address'') addresses = mock(''addresses'') addressable = mock_model(Organization, :id => "100", :addresses => addresses) Organization.stub!(:find_by_id).with("100").and_return(addressable) addressable.stub(:addresses).and_return(addresses) addresses.stub(:new).with({:these => ''params''}).and_return(address) post :create, :address => {:these => ''params''}, :organization_id => "100" assigns[:address].should equal(address) end class AddressesController < ApplicationController before_filter :load_addressable def create @address = @addressable.addresses.new(params[:address]) respond_to do |format| if @address.save flash[:notice] = ''Address was successfully created.'' format.html { redirect_to(@addressable) } format.xml { render :xml => @address, :status => :created, :location => @address } else format.html { render :action => "new" } format.xml { render :xml => @address.errors, :status => :unprocessable_entity } end end end private def load_addressable if params[:organization_id] @addressable = Organization.find_by_id(params[:organization_id]) end end end Notes: * I changed @parent_object to @addressable, since that''s how the association is labeled in the code. * The only object in the code example that uses mock_model is the one that is actually needs to behave like an AR model in the context of this example Let me know if you have any questions. Cheers, David
Sergey Rogachev
2009-Oct-19 15:47 UTC
[rspec-users] How to write a correct RSpec for Polymorphic Association
David Chelimsky wrote:> On Fri, Oct 16, 2009 at 7:21 AM, Sergey Rogachev <lists at ruby-forum.com> > wrote:....> DavidHi David, It doesn''t work, I got the following message: Mock ''addresses'' recieved unexcepted message :new with ({:these => ''params''}) Regards, Sergey -- Posted via http://www.ruby-forum.com/.
Sergey Rogachev
2009-Oct-19 15:48 UTC
[rspec-users] How to write a correct RSpec for Polymorphic Association
*unexpected message -- Posted via http://www.ruby-forum.com/.
David Chelimsky
2009-Oct-19 15:51 UTC
[rspec-users] How to write a correct RSpec for Polymorphic Association
On Mon, Oct 19, 2009 at 10:48 AM, Sergey Rogachev <lists at ruby-forum.com>wrote:> *unexpected message >Please copy the exact error instead of re-typing it. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20091019/79c65288/attachment.html>