我定義爲這樣的服務模式:獲得一些意外的錯誤,同時測試的Rails 3控制器
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
This all wor如我在瀏覽器中測試時所預期的那樣。但是當我嘗試在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"
測試全部通過,但其他人會失敗,因爲它無法在網頁上找到正確的選擇(S)。奇怪的是,返回的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標記的相反,我越來越只標明瞭網頁的DOCTYPE作爲HTML 4.
任何想法會導致什麼?
作爲第二個問題,我找不到任何方法來打開Webrat中的日誌記錄來查看實際發生的HTTP活動。我怎樣才能做到這一點?
也許使用wireshark來看看它從[?] – rogerdpack 2011-06-14 16:26:57