如何从Cucumber测试中获取控制器方法 - 或替代方案?

时间:2014-09-01 10:26:00

标签: ruby-on-rails ruby ruby-on-rails-4 cucumber capybara

我有一个具有User模型的应用程序,并且用户具有不同的角色。角色在内部表示为整数索引,但作为字符串呈现给用户。我还有一个辅助函数access_level(在application_controller.rb中 - 这是一个合理的位置吗?),它接受整数索引或字符串表示,并返回有关角色的大量信息的散列(包括字符串表示和索引,因此这是一种在它们之间进行转换的便捷方式)。如果重要,access_level依赖于config\initializers中文件中定义的角色定义。

因为呈现给用户的界面取决于角色,所以我的测试有许多诸如Given I have the role of administrator之类的东西。我尝试使用FactoryGirl.create(:user, role: access_level(role).index)创建用户,但我无法让Cucumber看到access_level

我通过谷歌搜索找到的大多数建议都表明"不要这样做"因为在幕后调用函数违反了将Cucumber保持在UI级别的原则,但我无法在没有Cucumber知道如何将角色名称映射到索引的情况下看到测试此用户行为的方法。我当然可以在我的一个Cucumber支持文件中复制access_level,但这违反了DRY。那么应该我如何构建它以便能够在Cucumber中干净地测试它?

2 个答案:

答案 0 :(得分:1)

Cucumber驱动程序模拟浏览器,因此步骤定义没有控制器实例或访问控制器实例方法。

使Cucumber步骤定义可用的控制器方法的最简单方法是使其成为类方法并使用ApplicationController.access_level调用它。然而,这将是icky,因为它会使步骤定义依赖于他们不应该知道的类。

相反,将要在应用程序和Cucumber步骤定义中使用的代码放入模块中,并将该模块包含在ApplicationController和Cucumber世界中。

在app / models / access_control.rb中:

module AccessControl
  def access_level(role)
    # do whatever is necessary
  end
end

(我猜它应该在models目录中,因为它对我来说感觉像模型级关注,但这并不重要。)

在app / controllers / application_controller.rb中:

class ApplicationController < ActionController::Base
  include AccessControl
  # ...
end

在features / support / env.rb中:

World AccessControl

答案 1 :(得分:0)

我被告知Cucumber场景应该复制用户行为。但这并不能否定您需要创建具有某些角色的某些用户进行测试的事实。将我们的自动化与站点代码分开并不会给我们使用现有控制器方法的奢侈/诱惑。 :)您是否考虑为用户工厂使用的角色创建工厂?我不确定在您的情况下会有多麻烦,或者您需要创建多少角色。