Expect_render(...).and_return('x')

Hi,

I’m trying to spec a controller method which renders some rjs as part
of a render :update block. The problem I’m having is that stub_render
or expect_render don’t seem to allow and_return to work.

The controller method does:

            if @thing.save
              render :update do |page|
                page.insert_html :bottom, 'x_thing_list', :partial

=> ‘thing’, :object => @thing
page.form.reset ‘x_new_thing’
end
else

If I expect/stub_render the partial render (which I need to do if I
want to solely test the controller in isolation), I get:

new Insertion.Bottom(“x_thing_list”, null);
Form.reset(“x_new_thing”);

The null is due to the render :partial being stubbed. Unfortunately,
this breaks the regex that assert_rjs uses, so my test:

response.should have_rjs(:insert, :bottom, “x_thing_list”)

fails, when it should pass.

What I need to be able to do is:

expect_render(:partial => ‘thing’, :object => @thing).and_return(’“x”’)

so that the output satisfies the assert_rjs regex. I would love to
provide a patch for this, but I cannot see why it doesn’t already
work. The expect_render return value seems to be a normal mock, I
don’t understand why return values aren’t working in this case.

Thanks for any insights.

I’ve experienced very strange behavior with expect_render and
stub_render as well as putting expectations on self in helper tests…
It seems a lot of this weirdness started when I upgraded the rails
plugin from 1.1.0 to 1.1.2. I use mocha instead of the rspec mocks -
don’t know if that is a cause…

On Jan 23, 2008 5:25 AM, Rob H. [email protected] wrote:

                page.insert_html :bottom, 'x_thing_list', :partial

so that the output satisfies the assert_rjs regex. I would love to
provide a patch for this, but I cannot see why it doesn’t already
work. The expect_render return value seems to be a normal mock, I
don’t understand why return values aren’t working in this case.

The trick here is that render :partial is NOT getting called on the
controller - it’s getting called on the template that is yielded to
render :update.

To make matters more confusing, you can’t get a handle on the template
until the action is already underway - which means you can’t say
template.expect_render or controller.template.expect_render.

Here’s the way I would handle this: Parked at Loopia

HTH,
David

David,

Thanks for looking at the problem.

The trick here is that render :partial is NOT getting called on the
controller - it’s getting called on the template that is yielded to
render :update.

I think I follow, still getting my head around that.

Here’s the way I would handle this: Parked at Loopia

I gave that a go, but the render :update line then triggers:

Mock ‘expect_render_mock_proxy’ asked to yield
|[#<Spec::Mocks::Mock:0x126ad08 @name=“template”>]| but no block was
passed

On Jan 25, 2008 7:19 AM, Rob H. [email protected] wrote:

Here’s the way I would handle this: Parked at Loopia

I gave that a go, but the render :update line then triggers:

Mock ‘expect_render_mock_proxy’ asked to yield
|[#<Spec::Mocks::Mock:0x126ad08 @name=“template”>]| but no block was
passed

Yeah - I was playing around w/ this locally and ran into the same
thing. I had made the change in rspec but not committed it yet. As of
trunk r3256, the block does get passed to the mock proxy.

That said, I’ve thought about this a bit more and realize that using
this approach gives up being able to use should have_rjs, which you
may not want to do.

It’s kind of a catch 22. You can either isolate the controller from
the views or not, but you can’t isolate it from 1/2 the views in a
given request. At least not with a bunch of magic that doesn’t yet
exist in rspec. To be honest, I’m not sure it should.

Cheers,
David