如何从控制器外部访问Rails控制器视图上下文?

And*_*rew 3 ruby-on-rails actionview actioncontroller actionviewhelper

我正在通过创建一个"普通的旧Ruby"presenter对象来清理一些依赖于某些自定义控制器辅助方法的代码.在我的控制器中,我能够将视图上下文传递给类:

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
Run Code Online (Sandbox Code Playgroud)

但是,我不确定在我的测试中应该通过什么.我宁愿动态地拉动helper/view_context,这样我就不必将其传入.

如何访问控制器外部的视图/控制器助手上下文?

这是一个Rails 3.2项目.

Jes*_*ido 9

比你想象的简单!(我找到了一条路,直到我失去了差不多一个小时)

您可以实例化ActionView

_view_context = ActionView::Base.new
Run Code Online (Sandbox Code Playgroud)

并在测试中使用它

FoobarPresenter.new(Foobar.new, _view_context)
Run Code Online (Sandbox Code Playgroud)

  • 在现代 Rails 中(例如 6.1), `ActionView::Base.new` 表示 `参数数量错误(给定 0,预期 3)` (5认同)

gmi*_*ile 5

如何测试期望值?

  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)
    
    Run Code Online (Sandbox Code Playgroud)
  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')
    
    Run Code Online (Sandbox Code Playgroud)