Ben, You're trying to test more than one thing in one spec. The gutter that's steered you into here is that you're looking for side-effects of a method you've mocked. Your spec says to make sure the template calls "body_class" and to have the call return a string, but that's not how the body_class method works: the real method passes that string along to "content_for," which is what causes it to end up in the layout.
There are really three responsibilities to specify: (1) the template is supposed to provide the right body_class, (2) the body_class method is supposed to format a string and pass it along to content_for, and (3) the layout is supposed to put that content into the body tag. For purposes of specifying the template's responsibility, I think you've got all you need by saying template.should_receive(:body_class).with("users") For the helper, you can just say in your helper spec self.should_receive(:content_for).with(:body_class, " class=\"funclass\"") body_class "funclass" Note that I'm mocking the receiver of the method being tested, which is a smell, but I think it's reasonable when dealing with app-specific helpers that rely on Rails helper methods. Also note that I'm specifying that you change your implementation to pass the content as the second argument to content_for. That's a lot less ugly to mock than the version with the block. I don't have a good recommendation for specifying the layout's responsibility for plopping the "body_class" content into the body tag, but I think it ought to be pretty easy to do readably. Maybe someone with more view-spec experience could help out. -hume. On Thu, Jan 24, 2008 at 11:00 AM, Ben Aldred <[EMAIL PROTECTED]> wrote: > Hi guys, > > I am a Rspec newbie and am having problems creating a spec for a RoR helper > method. > > I have in fact already implemented the helper method and am trying to create > retrospective specs. I know its the wrong way to do it but I am still > learning Rspec. > > In my view I have a call to a helper method. > > <% body_class "users" %> > > which sets a CSS class declaration in the content_for block which is then > used in the <body> tag in application.html.erb layout. > > def body_class(class_name) > content_for(:body_class) { " class=\"#{class_name}\"" } > end > > > I was trying the following in my view spec: > > template.should_receive (:body_class).with("users") > .and_return(' class="users"') > render "/admin/users/index.html.erb", :layout => "application" > response.should have_tag(' body.users') > > I get a: > > Expected at least 1 element matching "body.users", found 0. > <false> is not true. > > when I printed the response.body to screen it does not contain he CSS class > declaration on the body tag, where as running mongrel and going to the page > everything is fine. > > what am I doing wrong? I ended up doing: > > render "/admin/users/index.html.erb", :layout => "application" > response[:body_class].should == ' class="users"' > > I am interested to know why my first attempt did not work. > > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users