Dean
2011-Jul-08 21:37 UTC
[rspec-users] Trouble with RSpec mock "@macropost.should_receive(:save).and_return(true)" -- produces error expected :save with (any args) once, but received it 0 times
I''m getting the following RSpec failed test output when I run spec spec/controllers/macroposts_controller_spec.rb: http://pastie.org/2184821 Here''s the controller code for the "create" action for which the tests are failing: http://pastie.org/2184834 And here''s the relevant section of the macroposts_controller_spec.rb file: http://pastie.org/2184846 Finally, here are the factory definitions referenced in the _spec.rb file given above: http://pastie.org/2184863 Focusing on failures #1 and #2, it''s clear enough from the error messages that in the "POST create success" path through the specs, the @macropost object isn''t receiving :save. The site has no problem saving macroposts, but when I run the tests, the "if @macropost.save" line in the controller seems to never get executed, or the save process is failing silently, perhaps due to validation problems. When I try to walk through the process in the console (in the "test" environment) I''m able to produce a valid @macropost object that saves. Yet for some reason, my test specs cannot. Any suggestions? Obvious things I''ve missed? Additional info I can provide? Thanks! Dean Richardson -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110708/2463943c/attachment.html>
David Chelimsky
2011-Jul-10 11:00 UTC
[rspec-users] Trouble with RSpec mock "@macropost.should_receive(:save).and_return(true)" -- produces error expected :save with (any args) once, but received it 0 times
On Jul 8, 2011, at 5:37 PM, Dean wrote:> I''m getting the following RSpec failed test output when I run spec spec/controllers/macroposts_controller_spec.rb: > > http://pastie.org/2184821 > > Here''s the controller code for the "create" action for which the tests are failing: > > http://pastie.org/2184834 > > And here''s the relevant section of the macroposts_controller_spec.rb file: > > http://pastie.org/2184846 > > Finally, here are the factory definitions referenced in the _spec.rb file given above: > > http://pastie.org/2184863 > > Focusing on failures #1 and #2, it''s clear enough from the error messages that in the "POST create success" path through the specs, the @macropost object isn''t receiving :save. The site has no problem saving macroposts, but when I run the tests, the "if @macropost.save" line in the controller seems to never get executed, or the save process is failing silently, perhaps due to validation problems. > > When I try to walk through the process in the console (in the "test" environment) I''m able to produce a valid @macropost object that saves. Yet for some reason, my test specs cannot. > > Any suggestions? Obvious things I''ve missed? Additional info I can provide?The Project returned by "@project = Project.find(params[:project_id])" in the controller action is not the same object as the one defined in the spec. This is going to change in rails-3.1 (if you configure it to use the new identiy_map feature), but that is the case for all previous versions. To get the examples to work as written, you need to add: Project.stub(:find).and_return(@project) That should get these examples to pass, but there are a number of problems with the overall approach. One reason to use stubs is to isolate yourself from the real models. That way changes to validation rules, etc, don''t cause your controller specs to fail, and your specs run significantly faster as well. Since these examples use real models, you''re not getting the isolation benefit. Additionally, stubbing nested resources like this gets pretty complicated and difficult to maintain. Lastly, the controller action violates "Skinny Controller, Fat Model" [1], and that is complicating these specs quite a bit. With all that, I''d refactor the action to add the project and user IDs to the macropost hash, just interact with that model only, and move the mailer logic to an after_save hook on the model. The resulting controller and spec would look something like https://gist.github.com/1074456. Note that there is only one stub, and it is dead simple. The only thing keeping these examples slow now is the creation of a real User, but you could probably stub that out as well. HTH, David [1] http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model> Thanks! > > Dean Richardson-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110710/c09475b5/attachment-0001.html>
Jatin kumar
2011-Jul-10 12:03 UTC
[rspec-users] Trouble with RSpec mock "@macropost.should_receive(:save).and_return(true)" -- produces error expected :save with (any args) once, but received it 0 times
On Sun, Jul 10, 2011 at 4:30 PM, David Chelimsky <dchelimsky at gmail.com>wrote:> > On Jul 8, 2011, at 5:37 PM, Dean wrote: > > I''m getting the following RSpec failed test output when I run spec > spec/controllers/macroposts_controller_spec.rb: > > http://pastie.org/2184821 > > Here''s the controller code for the "create" action for which the tests are > failing: > > http://pastie.org/2184834 > > And here''s the relevant section of the macroposts_controller_spec.rb file: > > http://pastie.org/2184846 > > Finally, here are the factory definitions referenced in the _spec.rb file > given above: > > http://pastie.org/2184863 > > Focusing on failures #1 and #2, it''s clear enough from the error messages > that in the "POST create success" path through the specs, the @macropost > object isn''t receiving :save. The site has no problem saving macroposts, but > when I run the tests, the "if @macropost.save" line in the controller seems > to never get executed, or the save process is failing silently, perhaps due > to validation problems. > > When I try to walk through the process in the console (in the "test" > environment) I''m able to produce a valid @macropost object that saves. Yet > for some reason, my test specs cannot. > > Any suggestions? Obvious things I''ve missed? Additional info I can provide? > > > Hi David,> The Project returned by "@project = Project.find(params[:project_id])" in > the controller action is not the same object as the one defined in the spec. > This is going to change in rails-3.1 (if you configure it to use the new > identiy_map feature), >I had the same problem as above, and I used the same solution as you said.i.e. replacing should_receive with stub. However, I never got to understand why it worked. As you said, the objects returned in the spec are different but that is going to change in rails-3.1. Can you elaborate a bit on the details of the change. May be point me to a blog post written over it, and if there''s not one now, why not you write yourself one explaining the whole thing, when you find time. BTW, I am a great fan of yours and your blog has helped a lot, learning the basics of TDD by reading your articles and answers here & the rspec forum. but that is the case for all previous versions.> > To get the examples to work as written, you need to add: > > Project.stub(:find).and_return(@project) > > That should get these examples to pass, but there are a number of problems > with the overall approach. > > One reason to use stubs is to isolate yourself from the real models. That > way changes to validation rules, etc, don''t cause your controller specs to > fail, and your specs run significantly faster as well. Since these examples > use real models, you''re not getting the isolation benefit. > > Additionally, stubbing nested resources like this gets pretty complicated > and difficult to maintain. > > Lastly, the controller action violates "Skinny Controller, Fat Model" [1], > and that is complicating these specs quite a bit. > > With all that, I''d refactor the action to add the project and user IDs to > the macropost hash, just interact with that model only, and move the mailer > logic to an after_save hook on the model. The resulting controller and spec > would look something like https://gist.github.com/1074456. Note that there > is only one stub, and it is dead simple. > > The only thing keeping these examples slow now is the creation of a real > User, but you could probably stub that out as well. > > HTH, > David > > [1] http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model > > > > Thanks! > > Dean Richardson > > > > _______________________________________________ > 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/20110710/b71754f5/attachment.html>
David Chelimsky
2011-Jul-10 12:43 UTC
[rspec-users] Trouble with RSpec mock "@macropost.should_receive(:save).and_return(true)" -- produces error expected :save with (any args) once, but received it 0 times
On Jul 10, 2011, at 8:03 AM, Jatin kumar wrote:> On Sun, Jul 10, 2011 at 4:30 PM, David Chelimsky <dchelimsky at gmail.com> wrote: > > On Jul 8, 2011, at 5:37 PM, Dean wrote: > >> I''m getting the following RSpec failed test output when I run spec spec/controllers/macroposts_controller_spec.rb: >> >> http://pastie.org/2184821 >> >> Here''s the controller code for the "create" action for which the tests are failing: >> >> http://pastie.org/2184834 >> >> And here''s the relevant section of the macroposts_controller_spec.rb file: >> >> http://pastie.org/2184846 >> >> Finally, here are the factory definitions referenced in the _spec.rb file given above: >> >> http://pastie.org/2184863 >> >> Focusing on failures #1 and #2, it''s clear enough from the error messages that in the "POST create success" path through the specs, the @macropost object isn''t receiving :save. The site has no problem saving macroposts, but when I run the tests, the "if @macropost.save" line in the controller seems to never get executed, or the save process is failing silently, perhaps due to validation problems. >> >> When I try to walk through the process in the console (in the "test" environment) I''m able to produce a valid @macropost object that saves. Yet for some reason, my test specs cannot. >> >> Any suggestions? Obvious things I''ve missed? Additional info I can provide? > > Hi David, > > The Project returned by "@project = Project.find(params[:project_id])" in the controller action is not the same object as the one defined in the spec. This is going to change in rails-3.1 (if you configure it to use the new identiy_map feature), > > I had the same problem as above, and I used the same solution as you said.i.e. replacing should_receive with stub. However, I never got to understand why it worked. > > As you said, the objects returned in the spec are different but that is going to change in rails-3.1. > Can you elaborate a bit on the details of the change. > > May be point me to a blog post written over it, and if there''s not one now, why not you write yourself one explaining the whole thing, when you find time.Google "identity map in rails 3.1" There are a lot of posts about it.> BTW, I am a great fan of yours and your blog has helped a lot, learning the basics of TDD by reading your articles and answers here & the rspec forum. > > but that is the case for all previous versions. > > To get the examples to work as written, you need to add: > > Project.stub(:find).and_return(@project) > > That should get these examples to pass, but there are a number of problems with the overall approach. > > One reason to use stubs is to isolate yourself from the real models. That way changes to validation rules, etc, don''t cause your controller specs to fail, and your specs run significantly faster as well. Since these examples use real models, you''re not getting the isolation benefit. > > Additionally, stubbing nested resources like this gets pretty complicated and difficult to maintain. > > Lastly, the controller action violates "Skinny Controller, Fat Model" [1], and that is complicating these specs quite a bit. > > With all that, I''d refactor the action to add the project and user IDs to the macropost hash, just interact with that model only, and move the mailer logic to an after_save hook on the model. The resulting controller and spec would look something like https://gist.github.com/1074456. Note that there is only one stub, and it is dead simple. > > The only thing keeping these examples slow now is the creation of a real User, but you could probably stub that out as well. > > HTH, > David > > [1] http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model > > > >> Thanks! >> >> Dean Richardson-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110710/63c3afd1/attachment.html>
Dean
2011-Jul-12 18:29 UTC
[rspec-users] Trouble with RSpec mock "@macropost.should_receive(:save).and_return(true)" -- produces error expected :save with (any args) once, but received it 0 times
David: Wow, that''s just about the perfect example of a coding help forum reply: Specifically identifies what''s going wrong. Suggests a simple solution. Identifies the deeper underlying problem (code that''s too bloated, tightly-coupled, or whatever, and thus hard to test) Gently offers a detailed approach to address the underlying problem All without a hint of condescension. Thank you very much! This will help improve my code in many ways beyond the present problem. --Dean On Jul 10, 6:00?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Jul 8, 2011, at 5:37 PM, Dean wrote: > > > > > > > I''m getting the following RSpec failed test output when I run spec spec/controllers/macroposts_controller_spec.rb: > > >http://pastie.org/2184821 > > > Here''s the controller code for the "create" action for which the tests are failing: > > >http://pastie.org/2184834 > > > And here''s the relevant section of the macroposts_controller_spec.rb file: > > >http://pastie.org/2184846 > > > Finally, here are the factory definitions referenced in the _spec.rb file given above: > > >http://pastie.org/2184863 > > > Focusing on failures #1 and #2, it''s clear enough from the error messages that in the "POST create success" path through the specs, the @macropost object isn''t receiving :save. The site has no problem saving macroposts, but when I run the tests, the "if @macropost.save" line in the controller seems to never get executed, or the save process is failing silently, perhaps due to validation problems. > > > When I try to walk through the process in the console (in the "test" environment) I''m able to produce a valid @macropost object that saves. Yet for some reason, my test specs cannot. > > > Any suggestions? Obvious things I''ve missed? Additional info I can provide? > > The Project returned by "@project = Project.find(params[:project_id])" in the controller action is not the same object as the one defined in the spec. This is going to change in rails-3.1 (if you configure it to use the new identiy_map feature), but that is the case for all previous versions. > > To get the examples to work as written, you need to add: > > ? Project.stub(:find).and_return(@project) > > That should get these examples to pass, but there are a number of problems with the overall approach. > > One reason to use stubs is to isolate yourself from the real models. That way changes to validation rules, etc, don''t cause your controller specs to fail, and your specs run significantly faster as well. Since these examples use real models, you''re not getting the isolation benefit. > > Additionally, stubbing nested resources like this gets pretty complicated and difficult to maintain. > > Lastly, the controller action violates "Skinny Controller, Fat Model" [1], and that is complicating these specs quite a bit. > > With all that, I''d refactor the action to add the project and user IDs to the macropost hash, just interact with that model only, and move the mailer logic to an after_save hook on the model. The resulting controller and spec would look something likehttps://gist.github.com/1074456. Note that there is only one stub, and it is dead simple. > > The only thing keeping these examples slow now is the creation of a real User, but you could probably stub that out as well. > > HTH, > David > > [1]http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model > > > > > Thanks! > > > Dean Richardson > > > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users- Hide quoted text - > > - Show quoted text -- Hide quoted text - > > - Show quoted text -