[rspec-users] expect_render, why does there need to be a warning

David Chelimsky dchelimsky at gmail.com
Wed Aug 15 14:18:38 EDT 2007


On 8/15/07, Zach Dennis <zach.dennis at gmail.com> wrote:
> On 8/15/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > On 8/15/07, Zach Dennis <zach.dennis at gmail.com> wrote:
> > > On 8/14/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > > On 8/14/07, Zach Dennis <zach.dennis at gmail.com> wrote:
> > > > > On 8/14/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > > > > On 8/14/07, Zach Dennis <zach.dennis at gmail.com> wrote:
> > > > > > > There is a warning on the web site about expect_render and stub_render:
> > > > > > >
> > > > > > > "WARNING: expect_render and stub_render, while very useful, act
> > > > > > > differently from standard Message Expectations (a.k.a. mock
> > > > > > > expectations), which would never pass calls through to the real
> > > > > > > object. This can be very confusing when there are failures if you're
> > > > > > > not aware of this fact, because some calls will be passed through
> > > > > > > while others will not. This is especially confusing when you use
> > > > > > > stub_render because, as with all Method Stubs, you will get very
> > > > > > > little feedback about what is going on."
> > > > > > >
> > > > > > > My questions:
> > > > > > >
> > > > > > > Is this a sign that expect_render is doing to much?
> > > > > > > Is there a benefit from having expect_render and stub_render sometimes
> > > > > > > pass the render call to the underlying template object?
> > > > > > > Why not force all partials to be tested individually?
> > > > > > >
> > > > > > > Testing partials individually seems like a cleaner, more consistent
> > > > > > > and less confusing route to go, especially when you consider the
> > > > > > > nesting of paritals which render other partials.
> > > > > >
> > > > > > That's the whole reason for the existence of expect_render. If you're
> > > > > > spec'ing '_outer_partial' and you want to specify that it renders
> > > > > > '_inner_partial', but you don't want to actually render
> > > > > > '_inner_partial', there is no way to do that with traditional mocking
> > > > > > frameworks because they are not designed to pay attention to one call
> > > > > > to a method:
> > > > > >
> > > > > >   render(:partial => '_inner_partial')
> > > > > >
> > > > > > while letting another call to the same method:
> > > > > >
> > > > > >   render(:partial => '_outer_partial')
> > > > > >
> > > > > > through to the object. Agreed that expect_partial is doing to much,
> > > > > > but what alternatives do we have?
> > > > >
> > > > > When testing views the first call to render is going to be the one
> > > > > that should be passed to the underlying template, since this is from
> > > > > the test.
> > > > >
> > > > > Every subsequent call to render will be done from within the template,
> > > > > so RSpec can look for a matching expectation. It seems that
> > > > > expect_render is in charge of setting those up.
> > > > >
> > > > > If this is done then a simple convention will be enforced, every
> > > > > inline "render :partial" call will have to be expected in a view spec,
> > > > > and every view template (or partial) will have to have it's own view
> > > > > test.
> > > > >
> > > > > This gets rid of issues of nesting, confusion and poorly written specs
> > > > > where someone is asserting contents of a partial rendered multiple
> > > > > levels deep in the render chain.
> > > > >
> > > > > Granted you end up with more view tests, but they are cleaner, shorter
> > > > > and easier to read. More importantly they are easier to maintain and
> > > > > update because they will be easy to find an existing spec for to start
> > > > > test driving changes, rather then having to find the view which
> > > > > renders your partial and the spec that renders that view (and heaven
> > > > > forbid your partial is used  in several views, and each view tests the
> > > > > contents of that partial).
> > > >
> > > > I think you are describing a good convention, but I don't think rspec
> > > > should force it on everybody. The goal here is to provide tools that
> > > > ALLOW you to do things in certain ways but not force you to.
> > > >
> > > > For example, rspec_on_rails supports isolated views, but you can do
> > > > rails-style functional tests (using controller specs with integrated
> > > > views) if you want.
> > >
> > > How about a "integrate_inline_renders" similar to "integrate_views"?
> >
> > Just don't use expect_render and it'll do that. Magic!
> >
>
> I'm on the opposite view point. I don't want to pass through renders,
> I want to force all inline renders to be enforced.
>
> If i have a view that calls "render :partial => 'foo'" and I don't use
> expect_render I want it to yell at me saying an unexpected call was
> made on the template.

There's nothing else in rspec_on_rails that yells at you because you
don't like to organize your specs the way rspec thinks they should be
organized, so I definitely wouldn't support this being default
behaviour.

I could see, maybe, the possibility of having a command like
disallow_unexpected_renders or something like that, but I honestly
don't see that much value in it in return for the additional
complexity (didn't you start by saying this was too complex already?).

I understand that you DO see value in this, and I'd encourage you to
write a plugin that makes this work the way you want and feel free to
publish it.

Cheers,
David


More information about the rspec-users mailing list