我有一个带有一些功能的基本控制器,无法从外部访问基本控制器,没有路由匹配它。
然后,我用其他控制器扩展该控制器以添加额外的功能和路由,我有3个控制器扩展该基本控制器,只是为每个控制器定义3个方法。
我想测试基本控制器,但我不能做
post :index
因为该操作没有路由(没有路由匹配错误)
我不想将这些测试添加到这3个控制器中的一个,因为它们会发生很大变化(控制器在... 3周的广告系列中使用然后被删除)。
一些代码......:
基本控制器,CampaignController
class CampaignController < ApplicationController
def index
#some code...
end
def campaign_name
raise('campaign_name missing')
end
def campaign_url
raise('campaign_url missing')
end
#more actions....
end
其中一个可访问的控制器,SchoolCampaignController
class SchoolCampaignController < CampaignController
def campaign_name
'school'
end
def campaign_url
school_url
end
end
那些控制器基本上是这样的,但有时候我需要覆盖其中一个基本动作
那么,我做错了什么?我该如何正确测试CampaignController?
编辑:我不想测试那两个引发错误的方法,例如我想测试索引,或者其他一些操作(未显示)
我尝试过“response = controller.index”,但它没有调用before过滤器而且响应不是http响应,它只是该命令的输出(我不能做像...那样的期望。 。response.should render_template(xxxx)with that)
编辑2:为了绕过路由错误,我在before(:all)块中创建了测试内部的路由,然后路由不是问题,但现在,我得到有关非现有视图的错误(每个可访问controller实现所有视图,但抽象的视图具有非)
答案 0 :(得分:10)
您可以使用匿名控制器测试。这里很好地描述了它:https://relishapp.com/rspec/rspec-rails/v/3-6/docs/controller-specs/anonymous-controller。
它不需要任何路线猴子修补,就像以前的Rails.application.routes.draw do
一样。
例如:
describe BaseController, type: :controller do
controller do
def index
render text: "Hello World"
end
end
it "returns 200" do
get :index
expect(response).to have_http_status 200
end
end
答案 1 :(得分:9)
我猜您计划测试assigns
,session
和db
更改,而不是渲染视图。您可以重新绘制抽象控制器的路由,仅用于测试目的(https://gist.github.com/zilkey/543300处有一个示例)。
为了解决没有渲染视图的问题,我建议你围绕每个get
,post
,put
或delete
使用从no中解救的块-view-found错误(我写了一个小辅助函数来执行此操作)。如果您的控制器将视图呈现为最后一步,您仍应该能够检查分配,会话和数据库更改。
另一种方法是将测试编写为抽象控制器的特定实例,并将控制器名称和所需的任何数据分解出来。这样,您就不会遇到针对无功能控制器进行功能测试的问题,并且您可以轻松地每3周重写一次测试。