使用非RESTful路由重定向的RSpec控制器测试

时间:2013-11-08 05:28:31

标签: ruby-on-rails rspec

我正在尝试测试通过非标准路由集到达的控制器的一些基本方面。我似乎无法连接到LessonsController中的相应控制器/操作,这是通过重定向的路径到达CoursesController

当我运行我的规范时,我得到一个路由错误或响应变回空,我不知道如何解析有用的块。

# app/controllers/lessons_controller.rb
def index
  ... set some instance vars ...
end

# The CoursesController has index and show methods of its own which aren't used here

# app/config/routes.rb
...
get 'courses/:course_name' => redirect('/courses/%{course_name}/lessons'), :as => "course"
get 'courses/:course_name/lessons' => 'lessons#index', :as => "lessons"
...

# spec/controllers/courses_controller_spec.rb
describe CoursesController do
  it "test some instance vars" do
    get :show, :course_name => Course.first.title_url
    assigns(:some_ivar).should_not be_empty
  end
end

错误:

AbstractController::ActionNotFound: The action 'course' could not be found for CoursesController

RSpec尝试#2:

# spec/controllers/courses_controller_spec.rb
...
  get :course, :course_name => Course.first.title_url
...

尝试#2错误:

NoMethodError: undefined method `empty?' for nil:NilClass

如果我运行类似的试错方法,而不是从lessons_controller_spec.rb文件开始(例如在那里尝试get :index),我会遇到类似的错误。 lessons#index没有直接路由设置,只有重定向。

我的第二个例子中的响应对象是巨大的(尽管正文是空的)所以除非有人认为它有用,否则我不会包含它。

我非常后悔非RESTful架构,但鉴于它是什么,有没有想法如何让控制器规范针对LessonsController内的相应操作?

Rails 3.2.12,RSpec 2.14.4,Capybara 2.0.2

1 个答案:

答案 0 :(得分:3)

简短回答:不。

实际上,测试中有两种类型的get

一种类型用于控制器测试。这个get只能接受参数作为“动作”,比如说:index:show等等。所以你只能在当前的控制器测试中使用它。 (Doc在这里:http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-get

另一种类型用于集成测试。这个get可以接受任何路径作为参数。 http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-get

这两种类型具有相同的名称get,但用法不同。

您的问题是控制器测试。所以你使用第一个。您只能在CoursesController中访问操作。这就是你遇到错误的原因。

我强烈建议您立即修改路线。它不是关于RESTful,而是你的路线全天都在破坏转换。路径是教训的重点是什么,但控制器当然是什么?为什么你在没有路线的情况下写一个课程控制器?