ruby-on-rails - 如何从 Rails 4 中的辅助测试访问 Controller 辅助方法?

标签 ruby-on-rails ruby testing

我在 ApplicationController 中定义了一个方法作为辅助方法。

helper_method :can_access_participant_contact_data?

我正在尝试为驻留在辅助文件中的辅助方法编写测试。此辅助方法调用 helper_method :can_access_participant_contact_data?

# In participants_helper.rb
#
def redacted_contact_data participant, attribute_name
  attribute = participant.try(:contact_data).try(attribute_name)
  return attribute if can_access_participant_contact_data?(participant)
  return nil       if attribute.blank?
  return attribute.gsub(/\S/i, '*') # Asterisked string
end

到目前为止,我在测试中所做的就是调用 redacted_contact_data

require 'test_helper'

class ParticipantsHelperTest < ActionView::TestCase

   test "should return an asterisked string with spaces" do
     redacted_contact_data(Participant.first, :name)
   end

end

当我运行测试时,我收到这条消息

undefined method `can_access_participant_contact_data?' for #<ParticipantsHelperTest:0x007fd6c7c6d608>

我一直在四处寻找,但我不确定如何解决这个问题。我是否需要以某种方式模拟 can_access_participant_contact_data??或者我可以只将该方法包含在测试中吗?

最佳答案

AFAIK(据我所知),如果不对代码进行 stub 或做一些更改,就无法修复此问题,因为本质上,帮助程序文件只是其自身的一个模块,应独立于将包含它的位置进行处理。例如,谁知道您可能想在模型文件中包含这样的帮助文件,顺便说一下,模型文件中还有一个名为 can_access_participant_contact_data? 的方法,但与 ApplicationController 中定义的方法不同,因此您不能在不指定上下文/基础的情况下对其进行单元测试。

可能的解决方法:

  • stub :

    • 使用 Mocha 或将测试返工到 RSpec 中
    • 或手动(也许有更好的方法):

      test "should return an asterisked string with spaces" do
        ParticipantsHelper.class_eval do
          define_method :can_access_participant_contact_data? do |arg|
            true
          end
        end
      
        redacted_contact_data(Participant.first, :name)
      end
      
  • 或者,将您所有的 ApplicationController 帮助程序方法移动到一个单独的/现有的帮助程序文件中,比如在您已经存在的 ApplicationHelper 中。然后,将该帮助器包含在您正在测试的使用该方法的其他帮助器文件中。即:

    # helpers/application_helper.rb
    module ApplicationHelper
      def can_access_participant_contact_data?(participant)
        # YOUR CODE
      end
    end
    
    # helpers/participants_helper.rb
    module ParticipantHelper
      include ApplicationHelper
    
      def redacted_contact_data participant, attribute_name
        attribute = participant.try(:contact_data).try(attribute_name)
        return attribute if can_access_participant_contact_data?(participant)
        return nil       if attribute.blank?
        return attribute.gsub(/\S/i, '*') # Asterisked string
      end
    end
    
    • 如果使用这种方法,那么有两种方法可以在 Controller 中调用辅助方法:

      • 在 Controller 中使用 Rails helpers 方法:

        class ParticipantsController
          def show
            helpers.can_access_participant_contact_data?(@participant)
          end
        end
        
      • 或者,直接包括助手(我个人更喜欢上面的另一种方法)

        class ApplicationController < ActionController::Base
          include ApplicationHelper
        end
        
        class ParticipantsController < ApplicationController
          def show
            can_access_participant_contact_data?(@participant)
          end
        end
        
    • 对于 View 文件,您不需要更新任何代码。

关于ruby-on-rails - 如何从 Rails 4 中的辅助测试访问 Controller 辅助方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43658461/

相关文章:

ruby-on-rails - 从 10 基数除以 60 基数?

ruby-on-rails - 错误: `class_eval':没有这样的文件或目录 - getcwd (Errno::ENOENT)

ruby-on-rails - Postgresql 重复主键

ruby-on-rails - ROR 安装 "no such file to load"

ruby-on-rails - heroku - 缺少必需的参数 : aws_access_key_id, aws_secret_access_key,遵循 Hartl 教程

python - Django 客户端不会在测试中删除

Ruby:执行 bash 命令,捕获输出并同时转储到屏幕

ruby-on-rails - 警告 : Can't mass-assign protected attributes

ios - TestFlight - 构建权限列表中没有用户

android - 使用 Espresso 测试 Android PreferenceFragment