演示者中的自定义url辅助方法导致测试错误

时间:2016-03-30 13:51:24

标签: ruby-on-rails minitest

我正在为演示者类编写测试,并且在运行它们时遇到以下错误,来自自定义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的方法可以“降低”。以相同的方式通过模板。这只会影响测试,该方法在运行应用程序时效果很好。

任何帮助都非常感激。

修改

如果我从add_template_helper(PeopleHelper)删除person_presenter_test.rb,则错误为:

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: 在将people_helper.rb更新为以下内容以响应Shishir的回答后,错误消息保持不变:

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

2 个答案:

答案 0 :(得分:1)

方法content_tag返回一个字符串(实际上它是一个ActiveSupport::SafeBuffer,但你可以像字符串一样处理它),所以这不是你的问题。

您似乎使用ActiveRecord :: Base实例调用助手方法而不是url:

link_fa_to('envelope fa-1x', person) if person.email.present?

VS

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?

答案 1 :(得分:0)

您正在使用的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