Presenter 中的自定义 url 辅助方法导致测试错误
Custom url helper method in presenter causing test error
我正在为演示者编写测试 class,当 运行 它们来自自定义 url 辅助方法时,我收到以下错误。
Error:
PersonPresenterTest#test_0011_should get email icon:
ArgumentError: arguments passed to url_for can't be handled. Please require routes or provide your own implementation
app/helpers/people_helper.rb:4:in `link_fa_to'
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:59:in `block in <class:PersonPresenterTest>'
person_presenter_test.rb
class PersonPresenterTest < ActionView::TestCase
add_template_helper(PeopleHelper)
def setup
@person = FactoryGirl.create(:person)
@presenter = PersonPresenter.new(@person, view)
end
test 'should get email icon' do
expected = '<a class="icon-link" href="/people/1"><i class="fa fa-envelope fa-1x"></i></a>'
actual = @presenter.email_icon
assert_equal(expected, actual)
end
end
person_presenter.rb
class PersonPresenter < BasePresenter
presents :person
def email_icon
link_fa_to('envelope fa-1x', person) if person.email.present?
end
end
base_presenter.rb
class BasePresenter
def initialize(object, template)
@object = object
@template = template
end
def self.presents(name)
define_method(name) do
@object
end
end
def method_missing(*args, &block)
@template.send(*args, &block)
end
end
people_helper.rb
module PeopleHelper
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
end
routes.rb
Rails.application.routes.draw do
resources :organisations
resources :people
resources :reset_password, only: [:edit, :update, :new, :index, :create]
resources :dashboards, only: [:index]
resources :users
get 'profile' => 'users#show', as: :profile
controller :sessions do
get 'login' => :new
post 'login' => :create
end
get '/auth/:provider/callback', to: 'sessions#create'
get "sessions/create"
get 'sessions' => "sessions#destroy", as: :logout
root 'sessions#new'
end
我可以测试成功使用 link_to
的演示者方法,并且期望调用 link_fa_to
到 'fall' 的方法以相同的方式进入模板。这仅影响测试,该方法在 运行 应用程序时完美运行。
非常感谢任何帮助。
编辑:
如果我从 person_presenter_test.rb
中删除 add_template_helper(PeopleHelper)
,错误是:
Error:
PersonPresenterTest#test_0011_should get email icon:
NoMethodError: undefined method `link_fa_to' for #<#<Class:0x007fcdb6bb19e0>:0x007fcdb6bb15a8>
Did you mean? link_to
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:58:in `block in <class:PersonPresenterTest>'
编辑 2:
在响应 Shishir 的回答将 people_helper.rb
更新为以下内容后,错误消息保持不变:
module PeopleHelper
def link_fa_to(icon_name, link)
link_to link, class: "icon-link" do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end
end
end
您使用的 link_to 语法不接受 content_tag 作为参数。它只接受字符串。
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
尝试
link_to link do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end
方法content_tag
returns一个字符串(实际上是一个ActiveSupport::SafeBuffer
,但你可以像处理字符串一样处理它),所以这不是你的问题。
您似乎正在使用 ActiveRecord::Base 的实例而不是 url:
的实例来调用您的辅助方法
link_fa_to('envelope fa-1x', person) if person.email.present?
对比:
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
您可以尝试将代码更新为如下内容:
link_fa_to('envelope fa-1x', person_path(person)) if person.email.present?
我正在为演示者编写测试 class,当 运行 它们来自自定义 url 辅助方法时,我收到以下错误。
Error:
PersonPresenterTest#test_0011_should get email icon:
ArgumentError: arguments passed to url_for can't be handled. Please require routes or provide your own implementation
app/helpers/people_helper.rb:4:in `link_fa_to'
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:59:in `block in <class:PersonPresenterTest>'
person_presenter_test.rb
class PersonPresenterTest < ActionView::TestCase
add_template_helper(PeopleHelper)
def setup
@person = FactoryGirl.create(:person)
@presenter = PersonPresenter.new(@person, view)
end
test 'should get email icon' do
expected = '<a class="icon-link" href="/people/1"><i class="fa fa-envelope fa-1x"></i></a>'
actual = @presenter.email_icon
assert_equal(expected, actual)
end
end
person_presenter.rb
class PersonPresenter < BasePresenter
presents :person
def email_icon
link_fa_to('envelope fa-1x', person) if person.email.present?
end
end
base_presenter.rb
class BasePresenter
def initialize(object, template)
@object = object
@template = template
end
def self.presents(name)
define_method(name) do
@object
end
end
def method_missing(*args, &block)
@template.send(*args, &block)
end
end
people_helper.rb
module PeopleHelper
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
end
routes.rb
Rails.application.routes.draw do
resources :organisations
resources :people
resources :reset_password, only: [:edit, :update, :new, :index, :create]
resources :dashboards, only: [:index]
resources :users
get 'profile' => 'users#show', as: :profile
controller :sessions do
get 'login' => :new
post 'login' => :create
end
get '/auth/:provider/callback', to: 'sessions#create'
get "sessions/create"
get 'sessions' => "sessions#destroy", as: :logout
root 'sessions#new'
end
我可以测试成功使用 link_to
的演示者方法,并且期望调用 link_fa_to
到 'fall' 的方法以相同的方式进入模板。这仅影响测试,该方法在 运行 应用程序时完美运行。
非常感谢任何帮助。
编辑:
如果我从 person_presenter_test.rb
中删除 add_template_helper(PeopleHelper)
,错误是:
Error:
PersonPresenterTest#test_0011_should get email icon:
NoMethodError: undefined method `link_fa_to' for #<#<Class:0x007fcdb6bb19e0>:0x007fcdb6bb15a8>
Did you mean? link_to
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:58:in `block in <class:PersonPresenterTest>'
编辑 2:
在响应 Shishir 的回答将 people_helper.rb
更新为以下内容后,错误消息保持不变:
module PeopleHelper
def link_fa_to(icon_name, link)
link_to link, class: "icon-link" do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end
end
end
您使用的 link_to 语法不接受 content_tag 作为参数。它只接受字符串。
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
尝试
link_to link do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end
方法content_tag
returns一个字符串(实际上是一个ActiveSupport::SafeBuffer
,但你可以像处理字符串一样处理它),所以这不是你的问题。
您似乎正在使用 ActiveRecord::Base 的实例而不是 url:
的实例来调用您的辅助方法link_fa_to('envelope fa-1x', person) if person.email.present?
对比:
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
您可以尝试将代码更新为如下内容:
link_fa_to('envelope fa-1x', person_path(person)) if person.email.present?