I need to update something for a logged in user. My controller code for the action is: def som_action @_current_user.save_choice(params) end My application_controller.rb contains the following: class ApplicationController < ActionController::Base before_filter :current_user def current_user @_current_user ||= session[:current_user_id] && User.find(session[:current_user_id]) end end In my controller spec, I am trying something like this: let(:user) { mock_model("User", :id => 1001) } let(:item) { mock_model("Item", :id => 1010) } before(:each) do controller.stub!(:current_user).and_return(user) end describe "POST create" do context "when the user chooses an item" do it ''creates a item_choice'' do ItemChoice.should_receive(:new). with("requester_id" => user.id, "item_id" => item.id). and_return(item_choice) post :create, :item_choice => { "item_id" => item.id } response.should redirect_to(home_path) end end end I get nil object error when I run this spec, as there is no @_current_user set. How do I stub such that there is a user with an id to do this? raghu
On Mon, Nov 22, 2010 at 1:24 PM, Raghunandan Somaraju <somaraju at gmail.com> wrote:> I need to update something for a logged in user. My controller code for the > action is: > > def som_action > ?@_current_user.save_choice(params) > endyou are stubbing current_user, not @_current_user, thus this will fail. Maybe it would be more idiomatic to change this to def some_action current_user.save_choice( params ) end this should solve your setup problem too.> > My application_controller.rb contains the following: > > class ApplicationController < ActionController::Base > ?before_filter :current_user > > ?def current_user > ? ?@_current_user ||= session[:current_user_id] && > ? ? ?User.find(session[:current_user_id]) > ?end > end > > In my controller spec, I am trying something like this: > > ?let(:user) { mock_model("User", :id => 1001) } > ?let(:item) { mock_model("Item", :id => 1010) } > > ?before(:each) do > ? ?controller.stub!(:current_user).and_return(user) > ?end > > ?describe "POST create" do > ? ?context "when the user chooses an item" do > ? ? ?it ''creates a item_choice'' do > ? ? ? ?ItemChoice.should_receive(:new). > ? ? ? ? ?with("requester_id" => user.id, "item_id" => item.id). > ? ? ? ? ?and_return(item_choice)Maybe i missed something here, but where does item_choice come from, should that not be item?> ? ? ? ?post :create, :item_choice => { "item_id" => item.id } > ? ? ? ?response.should redirect_to(home_path) > ? ? ?end > ? ?end > ?end > > > I get nil object error when I run this spec, as there is no @_current_user > set. How do I stub such that there is a user with an id to do this? >HTH Cheers Robert -- The 1,000,000th fibonacci number contains ''42'' 2039 times; that is almost 30 occurrences more than expected (208988 digits). N.B. The 42nd fibonacci number does not contain ''1000000'' that is almost the expected 3.0e-06 times.
Thank you Robert. That works. I should have used the "current_user" instead of @_current_user in the first place. But, if I do want to use @_current_user, how do I pass on that instance variable to the controller from spec? Ignore the item_choice. It is a remnant of a piece that I edited off to simplify the question and concentrate on what I wanted. raghu Robert Dober wrote:> > On Mon, Nov 22, 2010 at 1:24 PM, Raghunandan Somaraju > <somaraju at gmail.com> wrote: >> I need to update something for a logged in user. My controller code for >> the >> action is: >> >> def som_action >> ?@_current_user.save_choice(params) >> end > you are stubbing current_user, not @_current_user, thus this will > fail. Maybe it would be more idiomatic to change this to > > def some_action > current_user.save_choice( params ) > end > > this should solve your setup problem too. >> >> My application_controller.rb contains the following: >> >> class ApplicationController < ActionController::Base >> ?before_filter :current_user >> >> ?def current_user >> ? ?@_current_user ||= session[:current_user_id] && >> ? ? ?User.find(session[:current_user_id]) >> ?end >> end >> >> In my controller spec, I am trying something like this: >> >> ?let(:user) { mock_model("User", :id => 1001) } >> ?let(:item) { mock_model("Item", :id => 1010) } >> >> ?before(:each) do >> ? ?controller.stub!(:current_user).and_return(user) >> ?end >> >> ?describe "POST create" do >> ? ?context "when the user chooses an item" do >> ? ? ?it ''creates a item_choice'' do >> ? ? ? ?ItemChoice.should_receive(:new). >> ? ? ? ? ?with("requester_id" => user.id, "item_id" => item.id). >> ? ? ? ? ?and_return(item_choice) > Maybe i missed something here, but where does item_choice come from, > should that not be item? >> ? ? ? ?post :create, :item_choice => { "item_id" => item.id } >> ? ? ? ?response.should redirect_to(home_path) >> ? ? ?end >> ? ?end >> ?end >> >> >> I get nil object error when I run this spec, as there is no >> @_current_user >> set. How do I stub such that there is a user with an id to do this? >> > HTH > Cheers > Robert > > -- > The 1,000,000th fibonacci number contains ''42'' 2039 times; that is > almost 30 occurrences more than expected (208988 digits). > N.B. The 42nd fibonacci number does not contain ''1000000'' that is > almost the expected 3.0e-06 times. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > >-- View this message in context: http://old.nabble.com/How-to-mock-a-logged-in-user-tp30278143p30283795.html Sent from the rspec-users mailing list archive at Nabble.com.
On Tue, Nov 23, 2010 at 1:04 PM, Raghu Somaraju <somaraju at gmail.com> wrote:> > Thank you Robert. That works. I should have used the "current_user" instead > of @_current_user in the first place. > > But, if I do want to use @_current_user, how do I pass on that instance > variable to the controller from spec?Short answer: Do not do it: Mocking is here to simulate behavior and ivars are here to implement state. (caching state in our case) Long answer: Although I believe that the above said is often true there must be exceptions, I adapted a relish test to show you how it works: https://gist.github.com/711904 Cheers Robert
Robert Dober wrote:> > On Tue, Nov 23, 2010 at 1:04 PM, Raghu Somaraju <somaraju at gmail.com> > wrote: >> >> Thank you Robert. That works. I should have used the "current_user" >> instead >> of @_current_user in the first place. >> >> But, if I do want to use @_current_user, how do I pass on that instance >> variable to the controller from spec? > > Short answer: Do not do it: Mocking is here to simulate behavior and > ivars are here to implement state. (caching state in our case) > > Long answer: Although I believe that the above said is often true > there must be exceptions, I adapted a relish test to show you how it > works: > https://gist.github.com/711904 > > Cheers > Robert > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > >Thank you once again Robert, for answering my question. I understand the reasoning. I realized it when you gave the solution to my original problem of this thread. But, out of curiosity wanted to know if it was possible. raghu -- View this message in context: http://old.nabble.com/How-to-mock-a-logged-in-user-tp30278143p30300615.html Sent from the rspec-users mailing list archive at Nabble.com.