Daniel Area Criações
2008-Dec-05 13:41 UTC
[rspec-users] proxy associantion on controllers
Hello, I''m trying learn Rspec but having problems to understand when and how user mocks and stubs. I have a properties_controller with to before_filter actions (check_administrator_role e load_user)... to access index action of properties_controller I need have a params[:user] and this parameter will be used to load ther user in method load_user ... Like bellow: before_filter :check_administrator_role before_filter :load_user # GET /properties def index @properties = @user.properties end private def load_user @user = User.find(params[:user_id]) if @user.nil? flash[:notice] = "Registro não encontrado" redirect_to root_path end end But I don''t know how test index and load_user without fixtures, take a look on my specs: describe PropertiesController do def mock_property(stubs={}) @mock_property ||= mock_model(Property, stubs) end before do @current_user = mock_model(User, :id => 1) controller.stub!(:check_administrator_role).and_return(true) @user = mock_model(User, :id=>1) controller.stub!(:load_user).and_return(@user) end describe "responding to GET index" do it "should expose all properties of given user as @properties" do @user.should_receive(:properties).and_return([mock_property]) get :index assigns[:properties].should == [mock_property] end end But I having this error: NoMethodError in ''PropertiesController responding to GET index should expose all properties of given user as @properties'' You have a nil object when you didn''t expect it! The error occurred while evaluating nil.properties /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:8:in `index'' ./spec/controllers/properties_controller_spec.rb:21: So, how is the right way to mock associated records? Thanks. Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/1f378360/attachment.html>
try: #@user = User.find(params[:user_id]) User.stub(:find).with(xx).and_return(@user) -- Posted via http://www.ruby-forum.com/.
On Fri, Dec 5, 2008 at 7:58 AM, Newman Huang <lists at ruby-forum.com> wrote:> > try: > > #@user = User.find(params[:user_id]) > User.stub(:find).with(xx).and_return(@user)Please quote enough of the email to which you are responding to provide enough context so that those of us who read email on our phones can understand. Cheers, David
Thanks Newman, I already try this but get strange error: before do @current_user = mock_model(User, :id => 1) controller.stub!(:check_administrator_role).and_return(true) User.stub(:find).with(1).and_return(@user) # <=<=<=<=<=< end The error: undefined method `stub'' for #<Class:0x23a5f3c> Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 11:58 AM, Newman Huang <lists at ruby-forum.com> wrote:> > try: > > #@user = User.find(params[:user_id]) > User.stub(:find).with(xx).and_return(@user) > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/2b3bfcab/attachment.html>
Daniel Lopes wrote:> Thanks Newman, I already try this but get strange error: > > before do > @current_user = mock_model(User, :id => 1) > controller.stub!(:check_administrator_role).and_return(true) > User.stub(:find).with(1).and_return(@user) # <=<=<=<=<=<Looks like a missing ''!'': User.stub!(:find).with(1).and_return(@user) # <=<=<=<=<=< -- Joseph Wilk> end > > The error: > undefined method `stub'' for #<Class:0x23a5f3c> > > > Atenciosamente, > > Daniel Lopes ? Area Cria??es > Design, Websites e Sistemas Web > > Visite: http://www.areacriacoes.com.br/projects > http://blog.areacriacoes.com.br/ > > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * > * * * * > 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 > > > On Fri, Dec 5, 2008 at 11:58 AM, Newman Huang <lists at ruby-forum.com > <mailto:lists at ruby-forum.com>> wrote: > > > try: > > #@user = User.find(params[:user_id]) > User.stub(:find).with(xx).and_return(@user) > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org <mailto:rspec-users at rubyforge.org> > http://rubyforge.org/mailman/listinfo/rspec-users > > > ------------------------------------------------------------------------ > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On Fri, Dec 5, 2008 at 8:07 AM, Daniel Lopes <danielvlopes at gmail.com> wrote:> Thanks Newman, I already try this but get strange error: > before do > @current_user = mock_model(User, :id => 1) > controller.stub!(:check_administrator_role).and_return(true) > User.stub(:find).with(1).and_return(@user) # <=<=<=<=<=<It''s stub!, not stub :) Cheers, David> end > The error: > undefined method `stub'' for #<Class:0x23a5f3c> > > Atenciosamente, > > Daniel Lopes ? Area Cria??es > Design, Websites e Sistemas Web > > Visite: http://www.areacriacoes.com.br/projects > http://blog.areacriacoes.com.br/ > > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * > * > 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 > > > On Fri, Dec 5, 2008 at 11:58 AM, Newman Huang <lists at ruby-forum.com> wrote: >> >> try: >> >> #@user = User.find(params[:user_id]) >> User.stub(:find).with(xx).and_return(@user) >> -- >> Posted via http://www.ruby-forum.com/. >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Thanks for help and sorry for insistance but I don''t understand aspects on rspec ( I think not understand how we use mocks and stubs): The behavior of my controller is... Before Filter: check_administrator_role load_user So, in this case I want run my before filter methods in before block on rspec, like below: describe PropertiesController do def mock_property(stubs={}) @mock_property ||= mock_model(Property, stubs) end before do @current_user = mock_model(User, :id => 1) <== define a current_user with id 1 controller.stub!(:check_administrator_role).and_return(true) <== and current_user is administrator @params = {:user_id=>1} <== define params User.stub!(:find).with(@params[:user_id]).and_return(@user) <== and now try fetch the user with id 1 end This line will define @user variable, right? User.stub!(:find).with(@params[:user_id]).and_return(@user) But I don''t need mock the @user variable to fill it with valid values ( like user_id, name, email and etc ) ? I think @user content is nil and get errors from will_paginate find method for this reason. describe "responding to GET index" do it "should expose all properties of given user as @properties" do @user.should_receive(:properties).and_return([mock_property]) get :index assigns[:properties].should == [mock_property] end end thanks. Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 12:16 PM, David Chelimsky <dchelimsky at gmail.com>wrote:> On Fri, Dec 5, 2008 at 8:07 AM, Daniel Lopes <danielvlopes at gmail.com> > wrote: > > Thanks Newman, I already try this but get strange error: > > before do > > @current_user = mock_model(User, :id => 1) > > controller.stub!(:check_administrator_role).and_return(true) > > User.stub(:find).with(1).and_return(@user) # <=<=<=<=<=<> > It''s stub!, not stub :) > > Cheers, > David > > > end > > The error: > > undefined method `stub'' for #<Class:0x23a5f3c> > > > > Atenciosamente, > > > > Daniel Lopes ? Area Cria??es > > Design, Websites e Sistemas Web > > > > Visite: http://www.areacriacoes.com.br/projects > > http://blog.areacriacoes.com.br/ > > > > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * > * > > * > > 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 > > > > > > On Fri, Dec 5, 2008 at 11:58 AM, Newman Huang <lists at ruby-forum.com> > wrote: > >> > >> try: > >> > >> #@user = User.find(params[:user_id]) > >> User.stub(:find).with(xx).and_return(@user) > >> -- > >> Posted via http://www.ruby-forum.com/. > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-users at rubyforge.org > >> http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/a40978bc/attachment-0001.html>
On 2008-12-05, at 10:06, Daniel Lopes wrote:> Thanks for help and sorry for insistance but I don''t understand > aspects on rspec ( I think not understand how we use mocks and stubs):Hi Daniel. If you''re a bit unsure about when to use mocks vs stubs, have a read of this article by Martin Fowler: http://martinfowler.com/articles/mocksArentStubs.html The short version of that article is: -You mock objects: @photo = mock_model Photo -You stub methods: @photo.stub!(:height).and_return(123)> The behavior of my controller is... > Before Filter: > check_administrator_role > load_userAre you using Authlogic?> So, in this case I want run my before filter methods in before block > on rspec, like below:Nope! =) before-filters are called when a controller action is called; they aren''t called in your specs'' "before" blocks.> describe PropertiesController do > def mock_property(stubs={}) > @mock_property ||= mock_model(Property, stubs) > end > > before do > @current_user = mock_model(User, :id => 1) <== define a > current_user with id 1 > controller.stub!(:check_administrator_role).and_return(true) <== > and current_user is administrator > @params = {:user_id=>1} <== define params > User.stub!(:find).with(@params[:user_id]).and_return(@user) <== > and now try fetch the user with id 1 > endKeep in mind that it''s before :each do or before :all do> This line will define @user variable, right? > User.stub!(:find).with(@params[:user_id]).and_return(@user)That line above tells the User class to return @user when #find is called on it with the argument @params[:user_id] . You don''t need to create a "params" variable. Eg: before :each do @user = mock_model User controller.stub!(:check_administrator_role).and_return(true) User.stub!(:find).and_return @user end> But I don''t need mock the @user variable to fill it with valid > values ( like user_id, name, email and etc ) ?If you want those methods, you''d stub them on @user, like this: @user = mock_model User, :name => ''Bob'' or like this: @user = mock_model User # ..some other code here.. @user.stub!(:name).with(no_args).and_return(''Bob'')> describe "responding to GET index" do > it "should expose all properties of given user as @properties" do > @user.should_receive(:properties).and_return([mock_property]) > get :index > assigns[:properties].should == [mock_property] > end > endThat looks about right. -Nick
Thanks a lot Nick... No, i''m not using Authlogic because already have base project with restful_authentication implemented with activation, roles and etc... and when I look authlogic the project was young, I don''t know now. About Martin Fowler post, I already readed... but the problem is because I know the diference between mocks and stubs ( mocks really call the method and it fail return a error, and stubs only return the result without check real method, right? ) but I don''t know how use it in RSpec... I''m starting understand now in this post ( my idea is copy this thread and translate to portuguese to help more people)... My doubt about mock and stubs is when I write this: @user = mock_model User => create mock object based on User and put in @user. but when I write the code below, the method User.name will not be called in this moment, but will be called when User class try to call name and will return ''Bob'' no matter what the real name method does... is this? @user.stub!(:name).and_return(''Bob'') About my previous code... I mocked User in instance variable @user but I have will_paginate installed and this bring a strange error when I try: @user.sohuld_receive(:properties).and_return([mock_property]) The error is: 1) NoMethodError in ''PropertiesController responding to GET index should expose all properties of given user as @properties'' undefined method `find'' for #<Class:0x23a0f64> /Users/daniellopes/Trabalhos/luvima/luvima/vendor/gems/mislav-will_paginate-2.3.6/lib/will_paginate/finder.rb:167:in `method_missing'' /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:61:in `load_user'' ./spec/controllers/properties_controller_spec.rb:20: spec/controllers/sessions_controller_spec.rb:102: My spec code is: describe PropertiesController do def mock_property(stubs={}) @mock_property ||= mock_model(Property, stubs) end before :each do @current_user = mock_model(User, :id => 1) controller.stub!(:check_administrator_role).and_return(true) User.stub!(:find).and_return(@user) end describe "responding to GET index" do it "should expose all properties of given user as @properties" do @user.should_receive(:properties).and_return([mock_property]) get :index assigns[:properties].should == [mock_property] end end And my controller code where error refer is: private def load_user @user = User.find(params[:user_id]) if @user.nil? flash[:notice] = "Registro não encontrado" redirect_to root_path end end Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 3:55 PM, Nick Hoffman <nick at deadorange.com> wrote:> On 2008-12-05, at 10:06, Daniel Lopes wrote: > >> Thanks for help and sorry for insistance but I don''t understand aspects on >> rspec ( I think not understand how we use mocks and stubs): >> > > Hi Daniel. If you''re a bit unsure about when to use mocks vs stubs, have a > read of this article by Martin Fowler: > http://martinfowler.com/articles/mocksArentStubs.html > > The short version of that article is: > -You mock objects: @photo = mock_model Photo > -You stub methods: @photo.stub!(:height).and_return(123) > > The behavior of my controller is... >> Before Filter: >> check_administrator_role >> load_user >> > > Are you using Authlogic? > > So, in this case I want run my before filter methods in before block on >> rspec, like below: >> > > Nope! =) before-filters are called when a controller action is called; > they aren''t called in your specs'' "before" blocks. > > describe PropertiesController do >> def mock_property(stubs={}) >> @mock_property ||= mock_model(Property, stubs) >> end >> >> before do >> @current_user = mock_model(User, :id => 1) <== define a current_user >> with id 1 >> controller.stub!(:check_administrator_role).and_return(true) <== and >> current_user is administrator >> @params = {:user_id=>1} <== define params >> User.stub!(:find).with(@params[:user_id]).and_return(@user) <== and now >> try fetch the user with id 1 >> end >> > > Keep in mind that it''s > before :each do > or > before :all do > > This line will define @user variable, right? >> User.stub!(:find).with(@params[:user_id]).and_return(@user) >> > > That line above tells the User class to return @user when #find is called > on it with the argument @params[:user_id] . > > You don''t need to create a "params" variable. Eg: > > before :each do > @user = mock_model User > controller.stub!(:check_administrator_role).and_return(true) > User.stub!(:find).and_return @user > end > > But I don''t need mock the @user variable to fill it with valid values ( >> like user_id, name, email and etc ) ? >> > > If you want those methods, you''d stub them on @user, like this: > @user = mock_model User, :name => ''Bob'' > or like this: > @user = mock_model User > # ..some other code here.. > @user.stub!(:name).with(no_args).and_return(''Bob'') > > describe "responding to GET index" do >> it "should expose all properties of given user as @properties" do >> @user.should_receive(:properties).and_return([mock_property]) >> get :index >> assigns[:properties].should == [mock_property] >> end >> end >> > > That looks about right. > -Nick > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/b5f80e31/attachment-0001.html>
Ashley Moran gave me help in another post that I open by accident when entries in the group, and now spec passed... But I still would like to understand more about mocks and stubs that I asked in previous email. Thanks again and sorry many emails. Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 6:19 PM, Daniel Lopes <danielvlopes at gmail.com> wrote:> Thanks a lot Nick... > No, i''m not using Authlogic because already have base project with > restful_authentication implemented with activation, roles and etc... and > when I look authlogic the project was young, I don''t know now. > > About Martin Fowler post, I already readed... but the problem is because I > know the diference between mocks and stubs ( mocks really call the method > and it fail return a error, and stubs only return the result without check > real method, right? ) but I don''t know how use it in RSpec... > > I''m starting understand now in this post ( my idea is copy this thread and > translate to portuguese to help more people)... My doubt about mock and > stubs is when I write this: > > @user = mock_model User => create mock object based on User and put in > @user. > > but when I write the code below, the method User.name will not be called in > this moment, but will be called when User class try to call name and will > return ''Bob'' no matter what the real name method does... is this? > @user.stub!(:name).and_return(''Bob'') > > > About my previous code... I mocked User in instance variable @user but I > have will_paginate installed and this bring a strange error when I try: > @user.sohuld_receive(:properties).and_return([mock_property]) > > The error is: > > 1) > NoMethodError in ''PropertiesController responding to GET index should > expose all properties of given user as @properties'' > undefined method `find'' for #<Class:0x23a0f64> > /Users/daniellopes/Trabalhos/luvima/luvima/vendor/gems/mislav-will_paginate-2.3.6/lib/will_paginate/finder.rb:167:in > `method_missing'' > /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:61:in > `load_user'' > ./spec/controllers/properties_controller_spec.rb:20: > spec/controllers/sessions_controller_spec.rb:102: > > My spec code is: > > describe PropertiesController do > > def mock_property(stubs={}) > @mock_property ||= mock_model(Property, stubs) > end > > before :each do > @current_user = mock_model(User, :id => 1) > controller.stub!(:check_administrator_role).and_return(true) > User.stub!(:find).and_return(@user) > end > > describe "responding to GET index" do > > it "should expose all properties of given user as @properties" do > @user.should_receive(:properties).and_return([mock_property]) > get :index > assigns[:properties].should == [mock_property] > end > > end > > > And my controller code where error refer is: > > private > def load_user > @user = User.find(params[:user_id]) > if @user.nil? > flash[:notice] = "Registro não encontrado" > redirect_to root_path > end > end > > Atenciosamente, > > Daniel Lopes ? Area Cria??es > Design, Websites e Sistemas Web > > Visite: http://www.areacriacoes.com.br/projects > http://blog.areacriacoes.com.br/ > > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * > * > 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 > > > On Fri, Dec 5, 2008 at 3:55 PM, Nick Hoffman <nick at deadorange.com> wrote: > >> On 2008-12-05, at 10:06, Daniel Lopes wrote: >> >>> Thanks for help and sorry for insistance but I don''t understand aspects >>> on rspec ( I think not understand how we use mocks and stubs): >>> >> >> Hi Daniel. If you''re a bit unsure about when to use mocks vs stubs, have a >> read of this article by Martin Fowler: >> http://martinfowler.com/articles/mocksArentStubs.html >> >> The short version of that article is: >> -You mock objects: @photo = mock_model Photo >> -You stub methods: @photo.stub!(:height).and_return(123) >> >> The behavior of my controller is... >>> Before Filter: >>> check_administrator_role >>> load_user >>> >> >> Are you using Authlogic? >> >> So, in this case I want run my before filter methods in before block on >>> rspec, like below: >>> >> >> Nope! =) before-filters are called when a controller action is called; >> they aren''t called in your specs'' "before" blocks. >> >> describe PropertiesController do >>> def mock_property(stubs={}) >>> @mock_property ||= mock_model(Property, stubs) >>> end >>> >>> before do >>> @current_user = mock_model(User, :id => 1) <== define a current_user >>> with id 1 >>> controller.stub!(:check_administrator_role).and_return(true) <== and >>> current_user is administrator >>> @params = {:user_id=>1} <== define params >>> User.stub!(:find).with(@params[:user_id]).and_return(@user) <== and >>> now try fetch the user with id 1 >>> end >>> >> >> Keep in mind that it''s >> before :each do >> or >> before :all do >> >> This line will define @user variable, right? >>> User.stub!(:find).with(@params[:user_id]).and_return(@user) >>> >> >> That line above tells the User class to return @user when #find is called >> on it with the argument @params[:user_id] . >> >> You don''t need to create a "params" variable. Eg: >> >> before :each do >> @user = mock_model User >> controller.stub!(:check_administrator_role).and_return(true) >> User.stub!(:find).and_return @user >> end >> >> But I don''t need mock the @user variable to fill it with valid values ( >>> like user_id, name, email and etc ) ? >>> >> >> If you want those methods, you''d stub them on @user, like this: >> @user = mock_model User, :name => ''Bob'' >> or like this: >> @user = mock_model User >> # ..some other code here.. >> @user.stub!(:name).with(no_args).and_return(''Bob'') >> >> describe "responding to GET index" do >>> it "should expose all properties of given user as @properties" do >>> @user.should_receive(:properties).and_return([mock_property]) >>> get :index >>> assigns[:properties].should == [mock_property] >>> end >>> end >>> >> >> That looks about right. >> -Nick >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/480ab796/attachment-0001.html>
On 5 Dec 2008, at 20:31, Daniel Lopes wrote:> Ashley Moran gave me help in another post that I open by accident > when entries in the group, and now spec passed... But I still would > like to understand more about mocks and stubs that I asked in > previous email.Yes I just noticed I re-answered a question that was solved hours ago :) Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/