Stub a controllers helper_method in a view template helper spec

My ApplicationController exposes a method (e.g. sort_direction) to the
view templates by using
helper_method :sort_direction.
I then use this method in another method (e.g. sort_link) in a view
helper (application_helper.rb).

When testing the sort_link method with RSpec (in
application_helper_spec.rb) I have to stub sort_direction as the test
seems to run completely independent from the controllers (and thereby
by to the view templates exposed methods).

Unfortunately I could not find out how to stub that sort_direction
method of the controller. I always get “undefined method”.

Here is what I tried so far (inside application_helper_spec.rb):

helper.stub(:sort_direction)
controller.stub(:sort_direction)
view.stub(:sort_direction)
self.stub(:sort_direction)

Here the error I get:

NoMethodError:
undefined method `sort_direction’ for
#<RSpec::Core::ExampleGroup::Nested_1

There is already some older blog post about that topic (http://
jakescruggs.blogspot.com/2007/03/mockingstubbing-partials-and-
helper.html), but it seems that this is not valid anymore for Rails 3
as there is no @controller.template.

How do I stub that method?

Kai

On Mar 21, 2011, at 5:41 AM, Kai S. wrote:

Unfortunately I could not find out how to stub that sort_direction
method of the controller. I always get “undefined method”.

Here is what I tried so far (inside application_helper_spec.rb):

helper.stub(:sort_direction)

This ^^ should work.

controller.stub(:sort_direction)
view.stub(:sort_direction)
self.stub(:sort_direction)

Here the error I get:

NoMethodError:
undefined method `sort_direction’ for
#<RSpec::Core::ExampleGroup::Nested_1

This error ^^ suggests that sort_direction is being called on the
example itself rather than the helper object. Please post the spec so we
can see what’s going on.

Cheers,
David

On 21 Mar 2011, at 10:41, Kai S. wrote:

Here the error I get:

NoMethodError:
undefined method `sort_direction’ for
#<RSpec::Core::ExampleGroup::Nested_1

From this error message, it looks like you can just def it inside your describe
block.

rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

cheers,
Matt

[email protected]
07974 430184

On Mar 21, 2011, at 8:40 AM, Kai S. wrote:

 controller.stub(:check_param)

def order_link(column, title = nil)
fetch_param(:order)

Change this ^^ to this:

helper.fetch_param(:order)

The problem is that ActionView::TestCase::Behavior, which helper specs
rely on, include the module being spec’d right in the spec, so you have
access to those methods directly.

RSpec expresses an opinion that the object should be wrapped instead by
providing a helper object that includes the module being spec’d, but
does not remove the module methods from the scope of the spec.

HTH,
David

This error ^^ suggests that sort_direction is being called on the example itself
rather than the helper object. Please post the spec so we can see what’s going on.

Sure …

describe ApplicationHelper do
describe “order link” do
it “should create html link” do
# things I tried
view.stub(:check_param)
helper.stub(:check_param)
controller.stub(:check_param)
self.stub(:check_param)

  order_link(:name)
end

end
end

Here is how check_param is called from within the helper:

module ApplicationHelper
def order_link(column, title = nil)
fetch_param(:order)
end
end

and in application controller:


helper_method :fetch_param

def fetch_param(name)

end

Change this ^^ to this:

helper.fetch_param(:order)

I was wrong the test fails also with the same error message:

Failure/Error: order_link(:name)
NoMethodError:
undefined method `fetch_param’ for #<#Class:0xb63d37ac:
0xb63be118>

On Mar 21, 2011, at 11:19 AM, Kai S. wrote:

Change this ^^ to this:

helper.fetch_param(:order)

I was wrong the test fails also with the same error message:

Failure/Error: order_link(:name)
NoMethodError:
undefined method `fetch_param’ for #<#Class:0xb63d37ac:
0xb63be118>

That’s not the same error message you posted earlier:

NoMethodError:
undefined method `sort_direction’ for
#<RSpec::Core::ExampleGroup::Nested_1

This ^^ message tells us that sort_direction is not implemented on the
example. The new message (above) tells us that fetch_param is not
implemented on the helper object, which means one of two things:

  1. fetch_param is not implemented as an instance method in the
    ApplicationHelper module. This would be just a matter of implementing
    it.

  2. ApplicationHelper is not included in the helper object. It should be
    included if the spec file is in spec/helpers. Is it?

Ok, the tests now runs fine, but unfortunately the site itself doesn’t
work anymore.
When the view gets rendered I get the following error:

undefined local variable or method `helper’ for #<#Class:0xb66566a0:
0xb665532c>

From this error message, it looks like you can just def it inside your describe
block.

Thanks Matt, that seems to work.

On Mar 21, 2011, at 11:15 AM, Kai S. wrote:

module ApplicationHelper
def order_link(column, title = nil)
fetch_param(:order)

Change this ^^ to this:

helper.fetch_param(:order)

Ok, the tests now runs fine, but unfortunately the site itself doesn’t
work anymore.
When the view gets rendered I get the following error:

undefined local variable or method `helper’ for #<#Class:0xb66566a0:
0xb665532c>

What’s the full backtrace?

Failure/Error: order_link(:name)
NoMethodError:
undefined method `fetch_param’ for #<#Class:0xb63d37ac:
0xb63be118>

That’s not the same error message you posted earlier:

NoMethodError:
undefined method `sort_direction’ for
#<RSpec::Core::ExampleGroup::Nested_1

The “#<#Class:0xb63d37ac” error shows up when using
helper.check_param in the order_link method as you suggested. The
“#<RSpec::Core::ExampleGroup::Nested_1” shows up with just using
check_param (without “helper.”).

This ^^ message tells us that sort_direction is not implemented on the example.
The new message (above) tells us that fetch_param is not implemented on the helper
object, which means one of two things:

  1. fetch_param is not implemented as an instance method in the ApplicationHelper
    module. This would be just a matter of implementing it.

It should be. It works when viewing that template in the browser.

  1. ApplicationHelper is not included in the helper object. It should be included
    if the spec file is in spec/helpers. Is it?

order_link is known and that is a method of ApplicationHelper, so I
guess it is included.

undefined local variable or method `helper’ for #<#Class:0xb66566a0:
0xb665532c>

What’s the full backtrace?

  1. ApplicationHelper order link should create html link
    Failure/Error: order_link(:name)
    NoMethodError:
    undefined method `fetch_param’ for #<#Class:0xb64ba0d0:
    0xb64a1ef4>

    ./app/helpers/application_helper.rb:43:in `order_link’

    ./spec/helpers/application_helper_spec.rb:22

    /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/

rspec/core/example.rb:49:in instance_eval' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example.rb:49:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example.rb:106:in with_around_hooks' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example.rb:46:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example.rb:99:in with_pending_capture' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example.rb:98:incatch’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example.rb:98:in with_pending_capture' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example.rb:45:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example_group.rb:262:in run_examples' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example_group.rb:258:inmap’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example_group.rb:258:in run_examples' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example_group.rb:232:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example_group.rb:233:in run' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/example_group.rb:233:inmap’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/example_group.rb:233:in run' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/command_line.rb:27:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/command_line.rb:27:in map' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/command_line.rb:27:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/reporter.rb:12:in report' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/command_line.rb:24:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/runner.rb:55:in run_in_process' # /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/ rspec/core/runner.rb:46:inrun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/gems/rspec-core-2.5.1/lib/
rspec/core/runner.rb:10:in `autorun’
# /home/kai/.rvm/gems/ruby-1.8.7-p330/bin/rspec:19

On Mar 21, 2011, at 12:52 PM, Kai S. wrote:

The “#<#Class:0xb63d37ac” error shows up when using
helper.check_param in the order_link method as you suggested.

That’s not what I meant to suggest.

In the spec, the method being spec’d should be invoked through the
helper:

it “does something” do
helper.method_being_specified
end

I did not mean to reference a helper object inside the implementation.

Make sense?

In the spec, the method being spec’d should be invoked through the helper:

it “does something” do
helper.method_being_specified
end

I did not mean to reference a helper object inside the implementation.

Make sense?

Ah, now I got it … you meant the template helper method (helpers
here and there and everywhere ;-)).

This works fine now:

it “should work” do
helper.stub(:fetch_param)
helper.order_link(:name)
end

Thanks a lot for your time and help, David.