Reputation: 6029
I'm trying to test some basic aspects of a controller that is reached via a nonstandard set of routes. I can't seem to connect to the appropriate controller/action in my LessonsController
, which is reached via redirected routes that are meant to appear to lead to the CoursesController
.
When I run my specs, I either get a routing error or the response comes back empty and I'm not sure how to parse it for useful nuggets.
# 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
The error:
AbstractController::ActionNotFound: The action 'course' could not be found for CoursesController
RSpec attempt #2:
# spec/controllers/courses_controller_spec.rb
...
get :course, :course_name => Course.first.title_url
...
The attempt #2 error:
NoMethodError: undefined method `empty?' for nil:NilClass
If I run similar trial-and-error approaches by instead starting with the lessons_controller_spec.rb
file (e.g. trying get :index
there), I get similar errors. There is no direct route set up for lessons#index
, only the redirects.
The response object in my second example is enormous (though the body is empty) so I won't include it unless someone thinks it's useful.
I'm definitely regretting the non-RESTful architecture, but given what it is, is there any idea how to get the controller spec to target the appropriate action inside the LessonsController
?
Rails 3.2.12, RSpec 2.14.4, Capybara 2.0.2
Upvotes: 0
Views: 1563
Reputation: 24815
Short answer: No.
Actually there are two types of get
available in tests.
One type is for controller testing. This get
can only accept argument as "action", say :index
, :show
etc. So you can only use it within current controller test. (Doc here: http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-get)
The other type is for integration testing. This get
can accept any path as argument. http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-get
The two types have same name get
but usage is different.
What in your question is controller testing. So you are use the first one. You can only reach actions inside CoursesController. That's why you meet error.
I strongly recommend you to revise the routes right now. It's not about RESTful or not, but your routes break conversion all the day. What's the point the path is lesson, but controller is course? And why you write a Course controller when there is no route for him?
Upvotes: 3