Как получить доступ к контексту представления контроллера Rails из-за пределов контроллера?

Я работаю над очисткой некоторого кода, который зависит от некоторых вспомогательных методов пользовательского контроллера, путем создания объекта-представителя «старого простого Ruby». В моем контроллере я могу передать контекст представления классу:

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

Тем не менее, я не уверен, что пройти в моем тесте. Я бы предпочел динамически вытягивать helper/view_context, чтобы мне не приходилось его передавать.

Как я могу получить доступ к вспомогательному контексту представления/контроллера вне контроллера?

Это проект Rails 3.2.


person Andrew    schedule 09.01.2015    source источник


Ответы (3)


Как насчет проверки ожиданий?

  1. Проверка контроллера (обратите внимание, что subject — это экземпляр контроллера, при условии, что мы тестируем с использованием 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)
    
  2. Тест для ведущего:

    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')
    
person gmile    schedule 10.01.2015
comment
Я думаю, что это, вероятно, лучший подход. Спасибо! - person Andrew; 10.01.2015

Проще, чем вы думаете! (Я потерял почти час, пока не нашел способ)

Вы можете создать экземпляр ActionView

_view_context = ActionView::Base.new

и использовать его в своем тесте

FoobarPresenter.new(Foobar.new, _view_context)
person Jesus Monzon Legido    schedule 01.03.2017
comment
Спасибо! Я пытался создать экземпляр в консоли рельсов, и это сделало это для меня. - person Philihp Busby; 19.05.2017

К сожалению, у меня нет идеального ответа для вас. Однако я покопался в библиотеке Draper Decorator, и они решили эту проблему.

В частности, у них есть класс HelperProxy и класс ViewContext, которые автоматически определяют нужный контекст.

https://github.com/drapergem/draper

У них также есть некоторые спецификации для обоих этих классов, которые, я уверен, вы могли бы позаимствовать при настройке своих собственных спецификаций.

person Bryce    schedule 10.01.2015
comment
Это хорошая идея. Я покопаюсь в источнике и посмотрю, смогу ли я что-нибудь найти. - person Andrew; 10.01.2015