How do I access the view context of a Rails controller from outside the controller?

I'm 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 can 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 prefer to dynamically move the helper / view_context so I don't have to skip it.

How can I access the view / controller helper context outside of the controller?

This is a Rails 3.2 project.

+3


source to share


3 answers


How about testing expectations?



  • Test for the controller (note which subject

    is an instance of the controller if we test with rspec-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)
    
          

  • Presenter test:

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

+3


source


Easier than you think! (I wasted almost an hour until I found a way)

You can instantiate ActionView

_view_context = ActionView::Base.new

      



and use it in your test

FoobarPresenter.new(Foobar.new, _view_context)

      

+4


source


Unfortunately, I don't have a perfect answer for you. However, I dug through the Draper Decorator library and they solved this problem.

In particular, they have a HelperProxy class and a ViewContext class that seem to automatically render the context you want.

https://github.com/drapergem/draper

They also have some specifications around both of these classes, which I'm sure you could borrow to customize your own specifications.

+2


source







All Articles