Rspec控制器在Rails中测试一个继承自AbstractController :: Base的控制器

Nic*_*rer 6 ruby rspec ruby-on-rails factory-bot

我正在为一个我没有构建的应用程序编写控制器测试,所以这肯定是一个学习过程.这是我第一次遇到直接从AbstractController :: Base继承的控制器.显然,它与其他控制器的行为不同.

其格式大致为:

class SchwadGenericController < AbstractController::Base
  def schwad_method var_one, var_two = nil, var_three = nil

    if var_two.blank?
      var_one.generic_method
    end

    render template: "schwad_templates/generic_template", layout: false
  end
end
Run Code Online (Sandbox Code Playgroud)

我尝试了正常测试,这是我目前所处的任何事情.

require 'rails_helper'

describe SchwadGenericController do
  # before(:each) do
  #     SchwadGenericController.skip_authorize_resource
  #   end
  # login_user
  let!(:variable){ create(:my_factory_variable) }


  describe 'controller methods' do

    it 'should hit this method' do
      binding.pry
      SchwadGenericController.schwad_method(variable)
      # expect(response).to_render template: "schwad_templates/generic_template"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

这里大致是我失败的地方.

Failures:

   1) SchwadGenericController controller methods should hit this method
      Failure/Error: Unable to find matching line from backtrace
     NoMethodError:
       undefined method `request=' for #   <SchwadGenericController:0x007f8022db0a20>
Run Code Online (Sandbox Code Playgroud)

我在这里阅读抽象控制器及其在rails中的作用:https://www.mobomo.com/2012/06/and-you-thought-render-farms-were-just-for-pixar/

我在这里阅读了文档:http://api.rubyonrails.org/classes/AbstractController/Base.html

我真的很感激另一组关于这一点,并指导你们如何测试控制器及其方法,控制器继承自AbstractController :: Base ....我缺少什么?

-Schwad

Bor*_*aMa 2

经过一些测试,我认为这是不可能的。控制器规范只是Rails 功能测试的包装器,它测试继承自ActionController::Base. 为了让控制器测试能够运行,控制器必须支持requestresponse对象,但情况并非如此AbstractController::Base(这些在 中定义ActionController::Base)。这就是为什么您在运行测试时会收到特定错误的原因。出于同样的原因,您将无法使用控制器规范帮助程序(期望),因为to_render它们仅为控制器规范而定义,并且您的控制器类不是“控制器规范”意义上的“控制器”。

您似乎唯一的测试选择是像任何其他普通 ruby​​ 类一样测试控制器。您需要将测试从spec/controllers目录移至其他目录,例如spec/abstract_controllers,然后您必须放弃所有控制器规范助手并测试仅调用实例方法,例如:

describe 'controller methods' do
  it 'should hit this method' do
    c = SchwadGenericController.new
    expect(c).to receive(:render).with(template: "schwad_templates/generic_template", layout: false)
    c.schwad_method(variable)
  end
end
Run Code Online (Sandbox Code Playgroud)