How to access a Rails controller view context from outside of a controller?
Solution 1
How about testing the expectations?
-
Test for controller (note that
subject
is the instance of the controller, assuming we're testing usingrspec-rails
):view_context = double("View context") foobar_presenter = double("FoobarPresenter") allow(subject).to receive(:view_context).and_return(view_context) allow(FoobarPresenter).to receive(:new).with(1, view_context).and_return(foobar_presenter) get :show, id: 1 expect(assigns(:foobar)).to eql(foobar_presenter)
-
Test for presenter:
view_context = double('View context', bad_helper_method: 'some_expected_result') presenter = FoobarPresenter.new(double('Model'), view_context) expect(presenter.something).to eql('some_expected_result')
Solution 2
Simpler than you think! (I lost almost an hour until I found a way)
You can instantiate an ActionView
_view_context = ActionView::Base.new
and use it in your test
FoobarPresenter.new(Foobar.new, _view_context)
Solution 3
I unfortunately don't have a perfect answer for you. However, I've dug through the Draper Decorator library, and they have solved this problem.
In particular, they have a HelperProxy class and a ViewContext class that seem to automatically infer the context that you want.
https://github.com/drapergem/draper
They also have some specs around both of these classes, which I'm sure you could borrow from in setting up your own specs.
Mike
Updated on June 27, 2022Comments
-
Mike almost 2 years
I am working on cleaning up some code that relies on some custom controller helper methods, by creating a "plain old Ruby" presenter object. In my controller, I am able to pass the view context to the class:
def show # old code: view_context.bad_helper_method @foobar = FoobarPresenter.new(Foobar.find(params[:id]), view_context) end class FoobarPresenter def initialize(model, view_context) @model = model @view_context = view_context end def something @view_context.bad_helper_method end end
However, I'm not sure what to pass in my test. I would rather pull the helper/view_context dynamically so that I don't have to pass it in.
How can I access the view/controller helper context outside of the controller?
This is a Rails 3.2 project.
-
Mike over 9 yearsThat's a good idea. I'll dig through the source and see if I can find something.
-
Mike over 9 yearsI think this is probably the best approach. Thanks!
-
Philihp Busby almost 7 yearsThanks! I was trying to instantiate one in a rails console, and this did it for me.
-
jrochkind almost 2 yearsIn modern rails (eg 6.1),
ActionView::Base.new
sayswrong number of arguments (given 0, expected 3)