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

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to