2011-06-14 36 views
0

我定義爲這樣的服務模式:獲得一些意外的錯誤,同時測試的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活動。我怎樣才能做到這一點?

+0

也許使用wireshark來看看它從[?] – rogerdpack 2011-06-14 16:26:57

回答

0

是的,沒關係。我是一個白癡,忘了把render_views放在我的測試裏面,這就是爲什麼它沒有渲染視圖

+0

得到的東西是什麼網站但我仍然很欣賞任何關於如何在webrat中啓用HTTP日誌記錄的信息。 – 2011-06-14 16:31:43

+0

可能希望將其添加爲單獨的問題。 – zetetic 2011-06-17 00:56:13