最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ruby on rails - How to make helper_methods available to Views in Rspec - Stack Overflow

programmeradmin0浏览0评论

We have some helper_methods in our controllers that are used across both the controller and the view they render.

For example:

helper_method :example_method
def example_method
  @example_method ||= nil
end

However when it comes to testing our views in Rspec we have hit errors that those methods don't exist (likely because the views are tested in isolation from the controller).

ActionView::Template::Error:
       undefined local variable or method `example_method' for #<ActionView::Base:0x0000000003b060>

We've tried mocking the methods in the specs like:

allow(view).to receive(:example_method).and_return(nil)

But that doesn't resolve the issue.

I know Devise solved this with their controller helpers: .rb and then including them into the Rspec setup:

config.include Devise::Test::ControllerHelpers, type: :view

Which means your views can access current_user, etc.

But it's not clear how to replicate this for our custom helper methods.

We have some helper_methods in our controllers that are used across both the controller and the view they render.

For example:

helper_method :example_method
def example_method
  @example_method ||= nil
end

However when it comes to testing our views in Rspec we have hit errors that those methods don't exist (likely because the views are tested in isolation from the controller).

ActionView::Template::Error:
       undefined local variable or method `example_method' for #<ActionView::Base:0x0000000003b060>

We've tried mocking the methods in the specs like:

allow(view).to receive(:example_method).and_return(nil)

But that doesn't resolve the issue.

I know Devise solved this with their controller helpers: https://github.com/heartcombo/devise/blob/fec67f98f26fcd9a79072e4581b1bd40d0c7fa1d/lib/devise/test/controller_helpers.rb and then including them into the Rspec setup:

config.include Devise::Test::ControllerHelpers, type: :view

Which means your views can access current_user, etc.

But it's not clear how to replicate this for our custom helper methods.

Share Improve this question asked Feb 6 at 17:16 CameronCameron 28.8k102 gold badges288 silver badges490 bronze badges 7
  • 1 You have completely misunderstood the purpose of Devise::Test::ControllerHelpers. Devise is based on the Warden middleware and the helper methods it generates do not work outside of the context of a HTTP request going through the middleware stack. Controller tests/specs (which you should not be using) don't, and the same applies to view specs. What the module provides is stubs. Despite the name the things are not connected. – max Commented Feb 6 at 17:38
  • I would argue that if you're testing the view in isolation it seems a bit stinky to expect a method lazily declared in some controller to be injected into the view context. It's not like there aren't other ways around it. – max Commented Feb 6 at 17:39
  • helper_method :example_method simply adds controller.send(:example_method,...), so since your view does not technically have a Controller this is going to be very difficult to test "in isolation", without completely mocking the entire concept, which you could do by simply defining a method (or if you need more methods creating your own module and including it) in the view eigenclass. – engineersmnky Commented Feb 6 at 17:49
  • @engineersmnky that's really complicated compared to just putting the method in a helper module and calling it with helpers.method_name in the controller. – max Commented Feb 6 at 17:58
  • 2 @LesNightingill 1 word: "abuse". Helpers and Concerns are substantially over used and mismanaged leading to leaky abstraction and tight coupling. I fully agree with separations of concerns and code reuse through modules and formal PORO objects but throw it in a "Helper" that is automagically include here there and everywhere, has always seemed like the nuclear approach to me. I find that people use both Helpers and Concerns as a cheap cop out to Presenters, Service Objects, functionesque Modules, and actual reusable code. – engineersmnky Commented Feb 6 at 22:03
 |  Show 2 more comments

1 Answer 1

Reset to default 0

So I managed to solve this by wrapping the stub with: without_partial_double_verification like so:

  before do
    without_partial_double_verification {
      allow(view).to receive(:example_method).and_return(nil)
    }
  end
发布评论

评论列表(0)

  1. 暂无评论