如何从控制器外部访问 Rails 控制器视图上下文?
How to access a Rails controller view context from outside of a controller?
我正在通过创建 "plain old Ruby" 演示对象来清理一些依赖于某些自定义控制器帮助器方法的代码。在我的控制器中,我能够将视图上下文传递给 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
但是,我不确定我的测试要通过什么。我宁愿动态地拉 helper/view_context 这样我就不必传递它了。
如何在控制器外部访问 view/controller 助手上下文?
这是一个 Rails 3.2 项目。
很遗憾,我没有适合您的完美答案。但是,我已经深入了解了 Draper Decorator 库,他们已经解决了这个问题。
特别是,他们有一个 HelperProxy class 和一个 ViewContext class,它们似乎可以自动推断出您想要的上下文。
https://github.com/drapergem/draper
他们也有一些关于这两个 classes 的规范,我相信您可以借鉴这些规范来设置自己的规范。
测试期望如何?
控制器测试(注意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)
主持人测试:
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')
比你想象的要简单! (我浪费了将近一个小时才找到方法)
您可以实例化一个 ActionView
_view_context = ActionView::Base.new
并在你的测试中使用它
FoobarPresenter.new(Foobar.new, _view_context)
基于 this answer 以下(稍作修改的版本)对我有用:
- 将以下内容添加到
rails_helper.rb
config.include ActionView::TestCase::Behavior, file_path: %r{spec/presenters}
(假设您的演示者 类 位于 /presenters
文件夹中)
- 在此之后,您可以通过
view
方法访问规范中的视图上下文:
FoobarPresenter.new(Foobar.new, view)
我正在通过创建 "plain old Ruby" 演示对象来清理一些依赖于某些自定义控制器帮助器方法的代码。在我的控制器中,我能够将视图上下文传递给 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
但是,我不确定我的测试要通过什么。我宁愿动态地拉 helper/view_context 这样我就不必传递它了。
如何在控制器外部访问 view/controller 助手上下文?
这是一个 Rails 3.2 项目。
很遗憾,我没有适合您的完美答案。但是,我已经深入了解了 Draper Decorator 库,他们已经解决了这个问题。
特别是,他们有一个 HelperProxy class 和一个 ViewContext class,它们似乎可以自动推断出您想要的上下文。
https://github.com/drapergem/draper
他们也有一些关于这两个 classes 的规范,我相信您可以借鉴这些规范来设置自己的规范。
测试期望如何?
控制器测试(注意
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)
主持人测试:
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')
比你想象的要简单! (我浪费了将近一个小时才找到方法)
您可以实例化一个 ActionView
_view_context = ActionView::Base.new
并在你的测试中使用它
FoobarPresenter.new(Foobar.new, _view_context)
基于 this answer 以下(稍作修改的版本)对我有用:
- 将以下内容添加到
rails_helper.rb
config.include ActionView::TestCase::Behavior, file_path: %r{spec/presenters}
(假设您的演示者 类 位于 /presenters
文件夹中)
- 在此之后,您可以通过
view
方法访问规范中的视图上下文:
FoobarPresenter.new(Foobar.new, view)