【问题标题】:Create a fake Rails request object创建一个伪造的 Rails 请求对象
【发布时间】:2019-07-28 11:12:20
【问题描述】:

我正在尝试为向 ActionController::Base 添加一些功能的 gem 编写测试。我想做这样的事情:

class TestController < ActionController::Base
  def index
    render json: { foo: "bar" }
  end
end

RSpec.describe "foo" do
  it "foo" do
    controller = TestController.new
    controller.process(:index)
  end
end

但是,当我这样做时,undefined method 'has_content_type?' for nil:NilClass 会出错,因为请求 herenil

如何创建“假”请求对象,以便可以在控制器上设置它,如下所示:

    controller = TestController.new
    controller.request = ?
    controller.process(:index)

【问题讨论】:

  • 测试rails控制器直接实例化它们并调用方法是不常见的(因为,正如你所经历的,没有请求对象)。我建议使用 RSpec 指南来测试控制器 relishapp.com/rspec/rspec-rails/docs/controller-specs
  • @Bustkiller 我在 Rails 应用程序上下文之外复制 rspec 控制器测试时遇到了一些问题。你有如何做到这一点的例子吗?
  • 对不起,我没有这样的例子。但是,您问题中的代码看起来很像 rails 应用程序。 “在 Rails 应用程序的上下文之外”是什么意思?
  • @Bustkiller 这些是对 gem 的测试,它为 actionpack 添加了一些功能,因此测试中没有应用程序上下文。
  • 我最接近的方法是创建一个 Rails 引擎(一种特殊的 gem),它将一些模型、作业和控制器添加到应用程序中,包括它。在这类项目中,通常会有一个虚拟测试应用程序,包括运行测试的 gem。这提供了一个 Rails 测试环境,您可以像在常规 Rails 应用程序中一样无缝地使用 RSpec

标签: ruby-on-rails ruby rspec actioncontroller


【解决方案1】:

控制器需要大量来自环境的信息来将信息解析为请求对象。因此,如果您尝试自己设置它,它可能过于复杂且容易损坏。

查看ActionController::TestCase 的文档:尽管不鼓励使用集成测试,但这可能是更适合功能测试的场景。

还有rspec-rails:如果你想在测试中构建一个临时控制器,它的控制器测试方法应该会很有帮助。 https://relishapp.com/rspec/rspec-rails/v/3-6/docs/controller-specs/anonymous-controller

【讨论】:

  • 我首先探索了 anonymous_controller 路线,但在没有启动完整的 Rails 应用程序的情况下让 rspec-rails 工作遇到了困难。有没有使用 rspec-rails 测试 action_controller 扩展的 gem 示例?
  • 遇到了什么困难?您可以采用 Rails 引擎的方式,并在 spec/dummy 文件夹中托管一个使用您的 gem 的单独虚拟应用程序。请参阅this article 了解快速介绍。
  • 这是我尝试 rspec 匿名控制器方法以及 ActionController::TestCase 方法的提交。在这两种情况下,框架似乎都假设了一个完整的 Rails 环境,所以我得到了像 NoMethodError: undefined method 'routes' for nil:NilClass github.com/jamesstonehill/api_error_handler/commit/… 这样的错误
【解决方案2】:

除非您正在做一些主要的低级工作,例如在 Rails 核心上工作,否则几乎没有任何理由伪造控制器。我之前已经为批处理控制器完成了它,并且由于 Rails 提供的所有额外价值,模拟完整请求非常复杂。即使您确实设法伪造了一个完整的请求-响应周期,您也会错过许多微妙的功能和极端情况,这违背了测试的目的。

我会转而依赖标准的集成测试基础架构,即通过检查使用它的控制器是否会按预期处理事情来验证您的 gem。如果你想验证你的某些函数是否被调用,你也可以使用 Mocha 之类的模拟框架,但即使这样通常也是多余的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 2019-09-21
    • 2017-05-25
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 2015-10-14
    相关资源
    最近更新 更多