我有一个如此定义的服务模型:
class Service < ActiveRecord::Base
attr_accessible :service_type #, ...
SERVICE_TYPES = {
:restaurant => "restaurant",
:retailer => "retailer"
}
SERVICE_TYPES.values.each do |method|
define_method method.pluralize.to_sym do
where(:service_type => method)
end
end
def domestic
where(:country => 'USA')
end
def international
where("country != 'USA'")
end
end
我决定不将传统的STI模式用于不同的服务,因为它们都具有相同的属性,并且行为相同。有一个父模型,但它仅用于规范化目的,Web用户永远不需要知道它。就应用程序而言,有些服务类型和特定服务。所以基本上我想要这样的网址:
http://myapp/services # <- Lists all service types
http://myapp/restaurants # <- Lists all restaurant-type services
http://myapp/restaurants/foo # <- Lists a specific restaurant (using friendly_id gem)
http://myapp/retailers # <- Lists all retailer-type services
http://myapp/retailers/bar # <- Lists a specific retailer
所以我创建了一个类似的路由模式:
controller :services, :via => [:get] do
match '/services' => :index
match '/:service_type' => :service_index, :as => 'service_type', :constraints => { :service_type => Regexp.new(Service::SERVICE_TYPES.values.map{|s| Regexp.escape(s.pluralize) }.join('|')) }
match '/:service_type/:id' => :show, :as => 'service', :constraints => { :service_type => Regexp.new(Service::SERVICE_TYPES.values.map{|s| Regexp.escape(s.pluralize) }.join('|')) }
end
哪个让我
services GET /services(.:format) {:controller=>"services", :action=>"index"}
service_type GET /:service_type(.:format) {:service_type=>/restaurants|retailers/, :controller=>"services", :action=>"service_index"}
service GET /:service_type/:id(.:format) {:service_type=>/restaurants|retailers/, :controller=>"services", :action=>"show"}
控制器定义为
class ServicesController < ApplicationController
def index
@service_types = Service::SERVICE_TYPES.values
@page_title = "Services"
end
def service_index
@service_type = params[:service_type]
@domestic = Service.send(@service_type).domestic
@international = Service.send(@service_type).international
@page_title = @service_type.capitalize
end
def show
@service = Service.find(params[:id])
@page_title = "Services - #{@service.name}"
end
end
当我在浏览器中测试时,这一切都按预期工作。但是当我尝试在Rspec2中运行集成测试时,我遇到了一些非常意外的行为。
require 'spec_helper'
describe ServicesController do
describe "GET 'index'" do
it "should be successful" do
get :index
response.should be_success
end
it "should have the right title" do
get :index
response.should have_selector(
"title",
:content => "#{@base_title}Services"
)
end
it "should have a link to each service" do
get :index
Service::SERVICE_TYPES.values.each do |service_type|
response.should have_selector("a", :href => service_type_path(service_type.pluralize),
:content => service_type.pluralize)
end
end
end
describe "GET 'service_index'" do
Service::SERVICE_TYPES.values.each do |service_type|
context service_type.pluralize do
it "should be successful" do
get :service_index, :service_type => service_type.pluralize
response.should be_success
end
it "should have the right title" do
get :service_index, :service_type => service_type.pluralize
response.should have_selector(
"title",
:content => "#{@base_title}#{service_type.pluralize.capitalize}"
)
end
it "should have a link to each service" do
get :service_index, :service_type => service_type.pluralize
Service.send(service_type.pluralize).each do |service|
response.should have_selector("a", :href => service_path(service_type.pluralize, service),
:content => service.name)
end
end
end
end
end
describe "GET 'show'" do
it "should be successful" do
get 'show'
response.should be_success
end
end
end
get
操作似乎成功运行,因为"should be successful"
测试全部通过,但其他操作失败,因为它无法在页面上找到正确的选择器。奇怪的是,返回的HTML转储似乎不是来自我的应用程序。
1) ServicesController GET 'index' should have the right title
Failure/Error: response.should have_selector(
expected following output to contain a <title>Services</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# ./spec/controllers/services_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
2) ServicesController GET 'index' should have a link to each service
Failure/Error: response.should have_selector("a", :href => service_type_path(service_type.pluralize),
expected following output to contain a <a href='/restaurants'>Restaurants</a> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# ./spec/controllers/services_controller_spec.rb:21:in `block (4 levels) in <top (required)>'
# ./spec/controllers/services_controller_spec.rb:20:in `each'
# ./spec/controllers/services_controller_spec.rb:20:in `block (3 levels) in <top (required)>'
3) ServicesController GET 'service_index' restaurants should have the right title
Failure/Error: response.should have_selector(
expected following output to contain a <title>Restaurants</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# ./spec/controllers/services_controller_spec.rb:37:in `block (5 levels) in <top (required)>'
4) ServicesController GET 'service_index' restaurants should have a link to each service
Failure/Error: response.should have_selector("a", :href => service_path(service_type.pluralize, service),
expected following output to contain a <a href='/restaurants/foo'>Foo</a> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# ./spec/controllers/services_controller_spec.rb:46:in `block (6 levels) in <top (required)>'
# ./spec/controllers/services_controller_spec.rb:45:in `block (5 levels) in <top (required)>'
我希望看到这确实是一个失败的是我的HTML应用程序模板的完全转储,该模板在HTML 5中标记。相反,我只获得标记为HTML 4的页面的doctype。
任何想法会导致什么?
作为次要问题,我无法想办法打开Webrat中的日志记录来查看实际发生的HTTP活动。我怎么能这样做?
答案 0 :(得分:0)
render_views
放在我的测试中,这就是为什么它没有渲染视图。