[rspec-users] stubbing helper methods for View specs

David Chelimsky dchelimsky at gmail.com
Fri Jul 6 14:27:47 EDT 2007


On 7/6/07, Jens-Christian Fischer <jcfischer.lists at gmail.com> wrote:
> Hi there
>
> I have several view specs, that include the following snippet in
> their "before" block to stub the methods by acts_as_authenticated
>
>    before :each do
>      @u = mock_model(User)
>      @u.should_receive(:name).and_return("Hans Muster")
>      template.should_receive(:logged_in?).and_return(true)
>      template.should_receive(:current_user).and_return(@u)
>    end
>
> this works for views / helpers like this:
>
>    it "should show bla" do
>      render "/layouts/thetool"
>      response.should have_tag("p", "bla")
>    end
>
> and the view (haml to make things more interesting)
>
>    - if logged_in?
>      %p bla
>
>
> Now I also use Ezra acl_system2 plugin which defines a "restrict_to"
> method that queries some roles. When I stub the methods above and run
> specs, I get the following error:
>
> ActionView::TemplateError in '/users/show should display the
> information of the user'
> undefined local variable or method `current_user' for
> #<Spec::Rails::DSL::ViewExampleController:0x35d5cc0>
> On line #59 of app/views/users/show.haml
>
>      56:       - @user.roles.each do |role|
>      57:         = role.title
>      58:
>      59: - restrict_to "admin | projektleiter" do
>      60:   = link_to "Bearbeiten", edit_user_url(@user)
>      app/views//users/show.haml:59
>      vendor/plugins/acl_system2/lib/caboose/access_control.rb:75:in
> `restrict_to'
>      (eval):2:in `restrict_to'
>      (eval):164:in `_render_haml_1'
>      vendor/plugins/haml/lib/haml/engine.rb:435:in `compile'
>      vendor/plugins/haml/lib/haml/engine.rb:186:in `to_html'
>      vendor/plugins/haml/lib/haml/template.rb:69:in `render'
>      vendor/rails/actionpack/lib/action_view/base.rb:502:in
> `delegate_render'
>      vendor/rails/actionpack/lib/action_view/base.rb:324:in
> `render_template_old'
>      vendor/plugins/haml/lib/haml/template.rb:96:in `render_template'
>      vendor/rails/actionpack/lib/action_view/base.rb:286:in
> `globalize_old_render_file'
>      vendor/plugins/trunk/lib/globalize/rails/action_view.rb:20:in
> `render_file'
>      vendor/rails/actionpack/lib/action_controller/base.rb:879:in
> `render_file'
>      vendor/rails/actionpack/lib/action_controller/base.rb:814:in
> `render_with_no_layout'
>      vendor/rails/actionpack/lib/action_controller/layout.rb:258:in
> `render_without_benchmark'
>      vendor/rails/actionpack/lib/action_controller/benchmarking.rb:
> 51:in `render'
>      /usr/local/lib/ruby/site_ruby/1.8/benchmark.rb:300:in `measure'
>      vendor/rails/actionpack/lib/action_controller/benchmarking.rb:
> 51:in `render'
>      vendor/plugins/rspec_on_rails/lib/spec/rails/dsl/behaviour/
> view.rb:51:in `render'
>      spec/views/users/show_haml_spec.rb:23
>      ...
>
>
>
> Interestingly, when I misspell the name of the stub in the working
> example, I get the following error:
>
> 1)
> ActionView::TemplateError in '/shared/layout_test not logged in
> should have the correct head information'
> undefined method `logged_in?' for #<ActionView::Base:0x22ec6f8>
> On line #13 of app/views/layouts/thetool.haml
>
> app/views//layouts/thetool.haml:13
>      app/helpers/application_helper.rb:5:in `login_logout'
>      (eval):28:in `_render_haml_1'
>      vendor/plugins/haml/lib/haml/engine.rb:435:in `compile'
>      vendor/plugins/haml/lib/haml/engine.rb:186:in `to_html'
>      vendor/plugins/haml/lib/haml/template.rb:69:in `render'
>      vendor/rails/actionpack/lib/action_view/base.rb:502:in
> `delegate_render'
>      vendor/rails/actionpack/lib/action_view/base.rb:324:in
> `render_template_old'
>      vendor/plugins/haml/lib/haml/template.rb:96:in `render_template'
>      vendor/rails/actionpack/lib/action_view/base.rb:286:in
> `globalize_old_render_file'
>      vendor/plugins/trunk/lib/globalize/rails/action_view.rb:20:in
> `render_file'
>      vendor/rails/actionpack/lib/action_controller/base.rb:879:in
> `render_file'
>      vendor/rails/actionpack/lib/action_controller/base.rb:814:in
> `render_with_no_layout'
>      vendor/rails/actionpack/lib/action_controller/layout.rb:258:in
> `render_without_benchmark'
>      vendor/rails/actionpack/lib/action_controller/benchmarking.rb:
> 51:in `render'
>      /usr/local/lib/ruby/site_ruby/1.8/benchmark.rb:300:in `measure'
>      vendor/rails/actionpack/lib/action_controller/benchmarking.rb:
> 51:in `render'
>      vendor/plugins/rspec_on_rails/lib/spec/rails/dsl/behaviour/
> view.rb:51:in `render'
>      spec/views/layouts/thetool_haml_spec.rb:16
>
>
> Note the different class (#<ActionView::Base:0x22ec6f8> vs
> #<Spec::Rails::DSL::ViewExampleController:0x35d5cc0>) in the two specs.
>
> I don't have enough rspec_fu to deduce where the problem lies..
>
>
> Any helpers?

In a nutshell - Rails compiles templates the first time they are
encountered in a given runtime. Combine this with the fact that mock
expectations are cleared out after every example, but the mock
framework doesn't have access to the compiled template, and you can
imagine that this is )(*&)(*ing nightmare-ish can of worms.

I thought I had a solution for this in trunk, but I've just discovered
some problems with it and am working to resolve them.

Sorry - can't be more helpful right now.

>
> thanks
> Jens-Christian
>
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list