roberto belardo
2008-Apr-06 11:20 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
Hi all, here i am again with this stupid problem in rspecing this controller action: ------------------------------------ CommentsController def create @comment = Comment.new(params[:comment]) @user = User.find(params[:user_id]) [16] @comment.author = @user @comment.save end ------------------------------------ CommentsController Spec describe CommentsController, "handling POST /comments" do before(:each) do @user = mock_model(User, :to_param => "2") @comment = mock_model(Comment, :to_param => "1", :author => @user) User.should_receive(:find).at_least(1).times.and_return(@user) Comment.stub!(:new).and_return(@comment) end def post_with_successful_save @comment.should_receive(:save).and_return(true) [34]post :create, :user_id => @user_id, :comment => {} end it "should create a new comment" do Comment.should_receive(:new).with({ }).and_return(@comment) [47]post_with_successful_save @comment.author.should be(@user) end end The frustrating error Rspec gave to me is this: Spec::Mocks::MockExpectationError in ''CommentsController handling POST /comments should create a new comment'' Mock ''Comment_1002'' received unexpected message :author= with (#<User:0x..fdb9c1a8e @name="User_1000">) comments_controller.rb:16:in `create'' comments_controller_spec.rb:34:in `post_with_successful_save'' comments_controller_spec.rb:47: I have tried to google for something like this but i resolved nothing. Could someone help me understanding my fault? Thanks in advance, Roberto. Inviato da Yahoo! Mail. La casella di posta intelligente. http://it.docs.yahoo.com/mail/overview/index.html
Jarkko Laine
2008-Apr-06 12:00 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
On 6.4.2008, at 14.20, roberto belardo wrote:> Hi all, > here i am again with this stupid problem in rspecing > this controller action: > > ------------------------------------ > CommentsController > def create > @comment = Comment.new(params[:comment]) > @user = User.find(params[:user_id]) > > [16] @comment.author = @user > > @comment.save > end > > ------------------------------------ > CommentsController Spec > describe CommentsController, "handling POST /comments" > do > > before(:each) do > @user = mock_model(User, :to_param => "2") > @comment = mock_model(Comment, :to_param => "1", > :author => @user) > > > User.should_receive(:find).at_least(1).times.and_return(@user) > > Comment.stub!(:new).and_return(@comment) > > end > > def post_with_successful_save > @comment.should_receive(:save).and_return(true) > > [34]post :create, :user_id => @user_id, :comment => {} > > end > > it "should create a new comment" do > Comment.should_receive(:new).with({ > }).and_return(@comment) > [47]post_with_successful_save > @comment.author.should be(@user) > end > > end > > The frustrating error Rspec gave to me is this: > > Spec::Mocks::MockExpectationError in > ''CommentsController handling POST /comments should > create a new comment'' > Mock ''Comment_1002'' received unexpected message > :author= with (#<User:0x..fdb9c1a8e > @name="User_1000">) > comments_controller.rb:16:in `create'' > comments_controller_spec.rb:34:in > `post_with_successful_save'' > comments_controller_spec.rb:47: > > > I have tried to google for something like this but i > resolved nothing. Could someone help me understanding > my fault?Short answer: you haven''t stubbed the author= method for the comment mock, only author. A bit longer answer: Are you sure you can trust the user to only submit valid user ids? With your current code, anyone can change the user_id parameter in the call and fake any user id she wants. This might be intentional (if there are only admin users in your app), just pointing it out. You can also simplify your action by just saying @user.comments.create(params[:comment]) once you have the user fetched. Cheers, //jarkko> > Thanks in advance, > Roberto. > > > Inviato da Yahoo! Mail. > La casella di posta intelligente. > http://it.docs.yahoo.com/mail/overview/index.html > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080406/fbb04287/attachment.bin
roberto belardo
2008-Apr-06 14:03 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
Thank you very much for you quick answer! Naturally now it works. Thanks for the long version note too. I already know that, and my code is just a test to play with rspec, but i really appreciate your note. Thank you for your help, see you the next problem, Roberto. :-) --- Jarkko Laine <jarkko at jlaine.net> ha scritto:> > On 6.4.2008, at 14.20, roberto belardo wrote: > > > Hi all, > > here i am again with this stupid problem in > rspecing > > this controller action: > > > > ------------------------------------ > > CommentsController > > def create > > @comment = Comment.new(params[:comment]) > > @user = User.find(params[:user_id]) > > > > [16] @comment.author = @user > > > > @comment.save > > end > > > > ------------------------------------ > > CommentsController Spec > > describe CommentsController, "handling POST > /comments" > > do > > > > before(:each) do > > @user = mock_model(User, :to_param => "2") > > @comment = mock_model(Comment, :to_param => > "1", > > :author => @user) > > > > > > >User.should_receive(:find).at_least(1).times.and_return(@user)> > > > Comment.stub!(:new).and_return(@comment) > > > > end > > > > def post_with_successful_save > > @comment.should_receive(:save).and_return(true) > > > > [34]post :create, :user_id => @user_id, :comment > => {} > > > > end > > > > it "should create a new comment" do > > Comment.should_receive(:new).with({ > > }).and_return(@comment) > > [47]post_with_successful_save > > @comment.author.should be(@user) > > end > > > > end > > > > The frustrating error Rspec gave to me is this: > > > > Spec::Mocks::MockExpectationError in > > ''CommentsController handling POST /comments should > > create a new comment'' > > Mock ''Comment_1002'' received unexpected message > > :author= with (#<User:0x..fdb9c1a8e > > @name="User_1000">) > > comments_controller.rb:16:in `create'' > > comments_controller_spec.rb:34:in > > `post_with_successful_save'' > > comments_controller_spec.rb:47: > > > > > > I have tried to google for something like this but > i > > resolved nothing. Could someone help me > understanding > > my fault? > > Short answer: you haven''t stubbed the author= method > for the comment > mock, only author. > > A bit longer answer: Are you sure you can trust the > user to only > submit valid user ids? With your current code, > anyone can change the > user_id parameter in the call and fake any user id > she wants. This > might be intentional (if there are only admin users > in your app), just > pointing it out. You can also simplify your action > by just saying > @user.comments.create(params[:comment]) once you > have the user fetched. > > Cheers, > //jarkko > > > > > Thanks in advance, > > Roberto. > > > > > > Inviato da Yahoo! Mail. > > La casella di posta intelligente. > > http://it.docs.yahoo.com/mail/overview/index.html > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > -- > Jarkko Laine > http://jlaine.net > http://dotherightthing.com > http://www.railsecommerce.com > http://odesign.fi > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersInviato da Yahoo! Mail. La casella di posta intelligente. http://it.docs.yahoo.com/mail/overview/index.html
roberto belardo
2008-Apr-08 20:06 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
Everything seemed so fine, but when i tried to investigate a little i discovered this tremendous behaviour of the spec: ------------------------------- CommentsController def create @comment = Comment.new(params[:comment]) @user = User.find(params[:user_id]) @comment.author = ''foooooobar'' @comment.save end ------------------------------- CommentsController Spec describe CommentsController, "handling POST/comments" do before(:each) do @user = mock_model(User, :to_param => "2") @comment = mock_model(Comment, :to_param => "1", :author => @user) User.should_receive(:find).at_least(1).times.and_return(@user) Comment.stub!(:new).and_return(@comment) @comment.stub!(:author=) end def post_with_successful_save @comment.should_receive(:save).and_return(true) @comment.should_receive(:author=) post :create, :user_id => @user_id, :comment => {} end it "should create a new comment" do Comment.should_receive(:new).with({}).and_return(@comment) post_with_successful_save @comment.author.should be(@user) end end ------------------------------- Autotest: ... 0 failures How can the spec pass if i test that @comment.author should be @user but in the controller i set a fooooobar string in the @comment.author? Better question: wich is the right way to test that create action to be sure, it will set the author of the comment? --- Jarkko Laine <jarkko at jlaine.net> ha scritto: ...> Short answer: you haven''t stubbed the author= method > for the comment > mock, only author. > > A bit longer answer: Are you sure you can trust the > user to only > submit valid user ids? With your current code, > anyone can change the > user_id parameter in the call and fake any user id > she wants. This > might be intentional (if there are only admin users > in your app), just > pointing it out. You can also simplify your action > by just saying > @user.comments.create(params[:comment]) once you > have the user fetched. > > Cheers, > //jarkko > > > > > Thanks in advance, > > Roberto. > > > > > > Inviato da Yahoo! Mail. > > La casella di posta intelligente. > > http://it.docs.yahoo.com/mail/overview/index.html > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > -- > Jarkko Laine > http://jlaine.net > http://dotherightthing.com > http://www.railsecommerce.com > http://odesign.fi > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersInviato da Yahoo! Mail. La casella di posta intelligente. http://it.docs.yahoo.com/mail/overview/index.html
Jarkko Laine
2008-Apr-08 20:35 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
On 8.4.2008, at 23.06, roberto belardo wrote:> Everything seemed so fine, but when i tried to > investigate a little i discovered this tremendous > behaviour of the spec: > > ------------------------------- CommentsController > def create > @comment = Comment.new(params[:comment]) > @user = User.find(params[:user_id]) > @comment.author = ''foooooobar'' > @comment.save > end > > ------------------------------- CommentsController > Spec > describe CommentsController, "handling POST/comments" > do > before(:each) do > @user = mock_model(User, :to_param => "2") > @comment = mock_model(Comment, :to_param => "1", > :author => @user) > > User.should_receive(:find).at_least(1).times.and_return(@user) > Comment.stub!(:new).and_return(@comment) > @comment.stub!(:author=) > end > > def post_with_successful_save > @comment.should_receive(:save).and_return(true) > @comment.should_receive(:author=) > post :create, :user_id => @user_id, :comment => {} > end > > it "should create a new comment" do > > Comment.should_receive(:new).with({}).and_return(@comment) > post_with_successful_save > @comment.author.should be(@user) > end > end > > ------------------------------- Autotest: > ... 0 failures > > How can the spec pass if i test that @comment.author > should be @user but in the controller i set a > fooooobar string in the @comment.author?Because @comment.should_receive(:author=) stubs the method so it has no effect after that. I would advice against using it in a general purpose helper such as post_with_successful_save and instead use it in an actual spec if needed.> > Better question: wich is the right way to test that > create action to be sure, it will set the author of > the comment?Since you''re testing that "@comment.author.should be(@user)", I see no reason to explicitly have "@comment.should_receive(:author=)". The former correctly tests the behaviour, whereas the latter checks the actual implementation, which in this case is superfluous. I hardly ever use should_receive with a setter method such as author=, but it might just be me. Cheers, //jarkko> > > > --- Jarkko Laine <jarkko at jlaine.net> ha scritto: > > ... > >> Short answer: you haven''t stubbed the author= method >> for the comment >> mock, only author. >> >> A bit longer answer: Are you sure you can trust the >> user to only >> submit valid user ids? With your current code, >> anyone can change the >> user_id parameter in the call and fake any user id >> she wants. This >> might be intentional (if there are only admin users >> in your app), just >> pointing it out. You can also simplify your action >> by just saying >> @user.comments.create(params[:comment]) once you >> have the user fetched. >> >> Cheers, >> //jarkko >> >>> >>> Thanks in advance, >>> Roberto. >>> >>> >>> Inviato da Yahoo! Mail. >>> La casella di posta intelligente. >>> http://it.docs.yahoo.com/mail/overview/index.html >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >> >> -- >> Jarkko Laine >> http://jlaine.net >> http://dotherightthing.com >> http://www.railsecommerce.com >> http://odesign.fi >> >> >>> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > > > Inviato da Yahoo! Mail. > La casella di posta intelligente. > http://it.docs.yahoo.com/mail/overview/index.html > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080408/3b54af44/attachment.bin
roberto belardo
2008-Apr-12 11:06 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
Uhm ok, i understood your answer but autotest did not. Better, this do not solves the problem. If i simply remove the "stub" and the "should_receive" for the author field, autotest will complain like this: Spec::Mocks::MockExpectationError in ''CommentsController handling POST /comments should create a new comment'' Mock ''Comment_1008'' received unexpected message :author= with (#<User:0x..fdb98f624 @name="User_1006">) and this was the reason why i put the "should_receive" and the "stub" on "author=" method, as someone told previously on this ml. :( Is there someone who knows how to spec this? Help needed. --- Jarkko Laine <jarkko at jlaine.net> ha scritto:> > On 8.4.2008, at 23.06, roberto belardo wrote: > > > Everything seemed so fine, but when i tried to > > investigate a little i discovered this tremendous > > behaviour of the spec: > > > > ------------------------------- CommentsController > > def create > > @comment = Comment.new(params[:comment]) > > @user = User.find(params[:user_id]) > > @comment.author = ''foooooobar'' > > @comment.save > > end > > > > ------------------------------- CommentsController > > Spec > > describe CommentsController, "handling > POST/comments" > > do > > before(:each) do > > @user = mock_model(User, :to_param => "2") > > @comment = mock_model(Comment, :to_param => > "1", > > :author => @user) > > > > >User.should_receive(:find).at_least(1).times.and_return(@user)> > Comment.stub!(:new).and_return(@comment) > > @comment.stub!(:author=) > > end > > > > def post_with_successful_save > > @comment.should_receive(:save).and_return(true) > > @comment.should_receive(:author=) > > post :create, :user_id => @user_id, :comment => > {} > > end > > > > it "should create a new comment" do > > > > >Comment.should_receive(:new).with({}).and_return(@comment)> > post_with_successful_save > > @comment.author.should be(@user) > > end > > end > > > > ------------------------------- Autotest: > > ... 0 failures > > > > How can the spec pass if i test that > @comment.author > > should be @user but in the controller i set a > > fooooobar string in the @comment.author? > > Because @comment.should_receive(:author=) stubs the > method so it has > no effect after that. I would advice against using > it in a general > purpose helper such as post_with_successful_save and > instead use it in > an actual spec if needed. > > > > > > Better question: wich is the right way to test > that > > create action to be sure, it will set the author > of > > the comment? > > Since you''re testing that "@comment.author.should > be(@user)", I see no > reason to explicitly have > "@comment.should_receive(:author=)". The > former correctly tests the behaviour, whereas the > latter checks the > actual implementation, which in this case is > superfluous. I hardly > ever use should_receive with a setter method such as > author=, but it > might just be me. > > Cheers, > //jarkko > > > > > > > > > --- Jarkko Laine <jarkko at jlaine.net> ha scritto: > > > > ... > > > >> Short answer: you haven''t stubbed the author> method > >> for the comment > >> mock, only author. > >> > >> A bit longer answer: Are you sure you can trust > the > >> user to only > >> submit valid user ids? With your current code, > >> anyone can change the > >> user_id parameter in the call and fake any user > id > >> she wants. This > >> might be intentional (if there are only admin > users > >> in your app), just > >> pointing it out. You can also simplify your > action > >> by just saying > >> @user.comments.create(params[:comment]) once you > >> have the user fetched. > >> > >> Cheers, > >> //jarkko > >> > >>> > >>> Thanks in advance, > >>> Roberto. > >>> > >>> > >>> Inviato da Yahoo! Mail. > >>> La casella di posta intelligente. > >>> > http://it.docs.yahoo.com/mail/overview/index.html > >>> _______________________________________________ > >>> rspec-users mailing list > >>> rspec-users at rubyforge.org > >>> > http://rubyforge.org/mailman/listinfo/rspec-users > >> > >> -- > >> Jarkko Laine > >> http://jlaine.net > >> http://dotherightthing.com > >> http://www.railsecommerce.com > >> http://odesign.fi > >> > >> > >>> _______________________________________________ > >> rspec-users mailing list > >> rspec-users at rubyforge.org > >> http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > Inviato da Yahoo! Mail. > > La casella di posta intelligente. > > http://it.docs.yahoo.com/mail/overview/index.html > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > -- > Jarkko Laine > http://jlaine.net > http://dotherightthing.com > http://www.railsecommerce.com > http://odesign.fi > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersInviato da Yahoo! Mail. La casella di posta intelligente. http://it.docs.yahoo.com/mail/overview/index.html
Jarkko Laine
2008-Apr-13 17:01 UTC
[rspec-users] Rspecing this simple controller it is driving me mad...
On 12.4.2008, at 14.06, roberto belardo wrote:> Uhm ok, i understood your answer but autotest did not. > Better, this do not solves the problem. > If i simply remove the "stub" and the "should_receive" > for the author field, autotest will complain like > this: > > Spec::Mocks::MockExpectationError in > ''CommentsController handling POST /comments should > create a new comment'' > Mock ''Comment_1008'' received unexpected message > :author= with (#<User:0x..fdb98f624 > @name="User_1006">) > > and this was the reason why i put the "should_receive" > and the "stub" on "author=" method, as someone told > previously on this ml. > :( > > Is there someone who knows how to spec this? Help > needed.Two ways: 1) either use Comment.new instead of mock_model(Comment) in your before block. This way your comment object has the ability to assign its author. 2) Use the mock model and your should_receive test. However, after that you cannot test that @comment.author.should be(@user) because you have stubbed author= and it doesn''t really do anything. So you just have to rely on that it works (like you should since it''s Rails code which you shouldn''t really be testing). //jarkko -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080413/80699141/attachment-0001.bin