如何在Rails 2.3中测试多态控制器? [英] How to test polymorphic controllers in Rails 2.3?
问题描述
亲爱的同花异草,
我将尽力说明我的问题的实质.预先感谢您的耐心等候.
I will try to give the essence of my issue. Thanks in advance for your patience.
我的多态控制器(Appointments
)由两个Views
访问,第一个属于Admin::Doctor
命名空间,第二个属于Patient
命名空间.
My Polymorphic Controller (Appointments
) is accessed by two Views
, the first belongs to Admin::Doctor
namespace and the second one to Patient
namespace.
routes.rb
的相关部分:
map.resources :patient do |patients|
patients.resources :appointments
end
map.namespace(:admin) do |admin|
admin.resources :doctor do |doctors|
doctors.resources :appointments
end
end
所以,我现在可以得到:
So, I can now get:
patients/:patient_id/appointments
admin/doctors/:doctor_id/appointments
...以及实际路线:
...and the actual routes:
rake routes | grep appointment
new_patient_appointments GET /patients/:patient_id/appointments/new(.:format) {:controller=>"appointments", :action=>"new"}
edit_patient_appointments GET /patients/:patient_id/appointments/edit(.:format) {:controller=>"appointments", :action=>"edit"}
patient_appointments GET /patients/:patient_id/appointments(.:format) {:controller=>"appointments", :action=>"show"}
PUT /patients/:patient_id/appointments(.:format) {:controller=>"appointments", :action=>"update"}
DELETE /patients/:patient_id/appointments(.:format) {:controller=>"appointments", :action=>"destroy"}
POST /patients/:patient_id/appointments(.:format) {:controller=>"appointments", :action=>"create"}
new_admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments/new(.:format) {:controller=>"admin/appointments", :action=>"new"}
edit_admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments/edit(.:format){:controller=>"admin/appointments", :action=>"edit"}
admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"show"}
PUT /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"update"}
DELETE /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"destroy"}
POST /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"create"}
我的模特:
class Patient
has_many :appointments, :as => :attendee
end
class Doctor
has_many :appointments, :as => :attendee
end
class Appointment
belongs_to :attendee, :polymorphic => true
end
我的控制器:
Controllers/Admin/doctors_controller.rb
class Admin::DoctorsController < AuthorisedController
end
Controllers/appointments_controller.rb
class AppointmentsController < ApplicationController
end
Controllers/patients_controller.rb
class PatientsController < ApplicationController
end
在我的test/functional/appointments_controller_test.rb
上,我正在测试patients
,没有错误,但是在测试doctors
时,我得到了ActionController::RoutingError
:
On my test/functional/appointments_controller_test.rb
, I am testing for patients
without errors but when testing for doctors
, I get an ActionController::RoutingError
:
4) Error:
test_should_show_doctor_appointment(AppointmentsControllerTest):
ActionController::RoutingError: No route matches {:controller=>"appointments", :id=>"281110143", :action=>"show", :doctor_id=>2}
test/functional/appointments_controller_test.rb:55:in `test_should_show_doctor_appointment'
测试中的相关部分:
test/functional/appointments_controller_test.rb
require 'test_helper'
class AppointmentsControllerTest < ActionController::TestCase
fixtures :patients, :appointments, :doctors, :users
# The following passes:
def setup
login_as :admin
end
test "should show patient appointment" do
get :show, :id => patients(:one).to_param, :appointment_id => appointments(:app_one).id
assert_response :success
end
# The following fails, giving the error mentioned above:
test "should show doctor appointment" do
get :show, :id => doctors(:one).to_param, :appointment_id => appointments(:app_one).id
assert_response :success
end
end
正如@Ryan所指出的那样,该测试位于基本名称空间下,因此,下一步,我在Admin
下创建了一个测试.
As @Ryan pointed out, the test is under the base namespace, so as a next step, I created a test under Admin
.
test/functional/admin/appointments_controller_test.rb
class Admin::AppointmentsControllerTest < ActionController::TestCase
fixtures :patients, :appointments, :doctors, :users
# The following passes:
def setup
login_as :admin
end
test "should show doctor appointment" do
get :show, :id => doctors(:one).to_param, :appointment_id => appointments(:app_one).id
assert_response :success
end
end
...现在我收到此错误:
...and now I get this error:
1) Error:
test_should_show_doctor_appointment(Admin::AppointmentsControllerTest):
RuntimeError: @controller is nil: make sure you set it in your test's setup method.
test/functional/admin/appointments_controller_test.rb:13:in `test_should_show_doctor_appointment'
这时,我在setup
方法下添加了@controller = AppointmentsController.new
,只是变得非常熟悉:
At this point, I added @controller = AppointmentsController.new
under the setup
method, only to get the very familiar:
1) Error:
test_should_show_doctor_appointments(Admin::AppointmentsControllerTest):
ActionController::RoutingError: No route matches {:action=>"show", :controller=>"appointments", :doctor_id=>2, :id=>"281110143"}
test/functional/admin/appointments_controller_test.rb:14:in `test_should_show_doctor_appointments'
在我看来,这就像一个恶性循环.
It seems to me like a vicious circle.
编辑结束
因此,由于测试找不到控制器,因为其路由指向admin/appointments
So, since the test can not find the controller because its route points at admin/appointments
- 为什么我能渲染
/admin/doctors/1/appointments
,因为appointments_controller.rb
既不在Admin
文件夹也不在Admin::
命名空间下(而是路由指向该目录)和 - 针对这种情况编写功能测试的最佳策略是什么?
- why am I able to render
/admin/doctors/1/appointments
since theappointments_controller.rb
does not live neither underAdmin
folder norAdmin::
namespace (but the route points there) and - what is the best strategy to write the functional tests for that case?
提前谢谢!
pR
推荐答案
此错误:
ActionController::RoutingError: No route matches {:controller=>"appointments", :id=>"281110143", :action=>"show", :doctor_id=>2}
表明您正在向名为AppointmentsController
的控制器发出请求,但要根据您的路线进行判断:
Shows that you're making a request to a controller called AppointmentsController
, but judging by your routes:
new_admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments/new(.:format) {:controller=>"admin/appointments", :action=>"new"}
edit_admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments/edit(.:format){:controller=>"admin/appointments", :action=>"edit"}
admin_doctor_appointments GET /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"show"}
PUT /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"update"}
DELETE /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"destroy"}
POST /admin/doctors/:doctor_id/appointments(.:format) {:controller=>"admin/appointments", :action=>"create"}
该路由仅在admin名称空间(即Admin::AppointmentsController
)内可用.
That route is only available within the admin namespace, i.e. Admin::AppointmentsController
.
我敢打赌,您正在执行类似describe AppointmentsController
而不是describe Admin::AppointmentsController
的操作.我不确定,因为您没有包括测试本身的关键部分.
I'm going to bet that you're doing something like describe AppointmentsController
rather than describe Admin::AppointmentsController
. I don't know for certain because you've not included the critical part that is the test itself.
这篇关于如何在Rails 2.3中测试多态控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!