测试基础(抽象)控制器

我有一个具有一些function的基本控制器,无法从外部访问基本控制器,没有路由匹配它。

然后,我用其他控制器扩展该控制器以添加额外的function和路由,我有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”,但是它没有调用beforefilter而且响应不是http响应,它只是该命令的输出(我不能做像…响应这样的期望。应该render_template(xxxx)

编辑2:绕过路由错误我在before(:all)块中创建了测试内部的路由,然后路由不是问题,但现在,我得到有关非现有视图的错误(每个可访问控制器实现所有观点,但抽象的有非)

我猜你计划测试assignssessiondb更改,而不是渲染视图。 您可以重新绘制抽象控制器的路由,仅用于测试目的( https://gist.github.com/zilkey/543300上有一个示例)。

为了解决没有渲染视图的问题,我建议你用一个从no-view-found错误中解救的块来包围每个getpostputdelete (我会编写一个小帮助函数来执行此操作)。 如果您的控制器将视图呈现为最后一步,您仍应该能够检查分配,会话和数据库更改。

另一种方法是将测试编写为抽象控制器的特定实例,并将控制器名称和所需的任何数据分解出来。 这样,您就不会遇到针对无法运行的控制器进行function测试的问题,并且您可以轻松地每3周重写一次测试。

您可以使用匿名控制器测试。 这里有很好的描述: 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