[rspec-users] Stub a controllers helper_method in a view template helper spec

1,579 views
Skip to first unread message

Kai Schlamp

unread,
Mar 21, 2011, 6:41:35 AM3/21/11
to rspec...@rubyforge.org
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
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

David Chelimsky

unread,
Mar 21, 2011, 7:36:22 AM3/21/11
to rspec-users
On Mar 21, 2011, at 5:41 AM, Kai Schlamp wrote:

> 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)

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

Matt Wynne

unread,
Mar 21, 2011, 7:43:11 AM3/21/11
to rspec-users

On 21 Mar 2011, at 10:41, Kai Schlamp wrote:

> 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

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

>
> 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
> _______________________________________________
> rspec-users mailing list
> rspec...@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

cheers,
Matt

ma...@mattwynne.net
07974 430184

Kai Schlamp

unread,
Mar 21, 2011, 9:40:51 AM3/21/11
to rspec...@rubyforge.org
> 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
...

David Chelimsky

unread,
Mar 21, 2011, 10:08:47 AM3/21/11
to rspec-users

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

>> 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)

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

Kai Schlamp

unread,
Mar 21, 2011, 12:19:09 PM3/21/11
to rspec...@rubyforge.org
> 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>

David Chelimsky

unread,
Mar 21, 2011, 1:14:16 PM3/21/11
to rspec-users
On Mar 21, 2011, at 11:19 AM, Kai Schlamp 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?

Kai Schlamp

unread,
Mar 21, 2011, 12:15:03 PM3/21/11
to rspec...@rubyforge.org
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>

> > module ApplicationHelper
> >  def order_link(column, title = nil)
> >    fetch_param(:order)
>
> Change this ^^ to this:
>
>   helper.fetch_param(:order)

Kai Schlamp

unread,
Mar 21, 2011, 1:09:59 PM3/21/11
to rspec...@rubyforge.org
> From this error message, it looks like you can just def it inside your describe block.

Thanks Matt, that seems to work.

David Chelimsky

unread,
Mar 21, 2011, 1:29:10 PM3/21/11
to rspec-users
On Mar 21, 2011, at 11:15 AM, Kai Schlamp 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?

Kai Schlamp

unread,
Mar 21, 2011, 1:52:14 PM3/21/11
to rspec...@rubyforge.org
> > 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.

> 2) 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.

Kai Schlamp

unread,
Mar 21, 2011, 2:12:49 PM3/21/11
to rspec...@rubyforge.org
> > 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:in `run'
# /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:in `run'
# /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:in `catch'
# /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:in `run'
# /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:in `map'
# /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:in `run'
# /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:in `map'
# /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:in `run'
# /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:in `run'
# /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:in `run'
# /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:in `run'
# /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

David Chelimsky

unread,
Mar 21, 2011, 2:52:48 PM3/21/11
to rspec-users
On Mar 21, 2011, at 12:52 PM, Kai Schlamp wrote:

>>> 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.

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?

Kai Schlamp

unread,
Mar 21, 2011, 5:10:12 PM3/21/11
to rspec...@rubyforge.org
> 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.

Reply all
Reply to author
Forward
0 new messages