[rspec-users] How to mock an object defined in the before_filter function?

Pat Maddox pat.maddox at gmail.com
Wed Feb 25 20:03:03 EST 2009

On Wed, Feb 25, 2009 at 2:40 PM, Evgeny Bogdanov
<evgeny.bogdanov at gmail.com> wrote:
> The function to specify and specification for it are below.
> Comment.stub!(:find).and_return(@comment)
> does what I need.
> However, it strongly depends on the implementation of find_comment
> function,
> and if I change it to, let's say, this one:
>    def find_comment
>       @space = Space.find(1)
>       @comment = @space.comment
>     end

My personal opinion is that the semantics of your app have changed, so
at least some spec somewhere should have to change with it.  There are
a lot of people who don't agree with that.

> my spec will fail. Moreover, in my spec I'm checking if the
> destroy.rjs is returned on request,
> and I don't care about @comment and find_comment. Thus, I would like
> just to mock the whole
> object @comment for the function "destroy" like it is done with
> assigns for view specs, so that my spec doesn't depend on it at all.

I would wrap the stubbing stuff in a method, so that you clearly show
in your test that you don't care about the comment.  e.g.

# spec_helper.rb
def stub_comment
  c = mock_model(Comment)
  Comment.stub!(:find).and_return c

describe CommentsController, "DELETE /comments/1" do
  before(:each) do


Another alternative is to not use a @comment ivar in your controllers
and instead to use a method.  e.g.

def comment
  @comment ||= Comment.find params[:id]

and wherever you reference @comment in the controller, ref the method
comment instead.  Then in your spec you can stub it.

You need to inject your mock somehow, but due to the design of Rails
controllers you can't really just "set" something in there, so you
need to either use a factory method which you stub in the controller
spec, or stub out the finder.  If you think that the setup is too
verbose, wrap it in an intention-revealing method.



More information about the rspec-users mailing list