Получение некоторых неожиданных ошибок при тестировании контроллера Rails 3 - PullRequest
0 голосов
/ 14 июня 2011

У меня есть определенная модель услуг:

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 для разных сервисов, поскольку все они будут иметь одинаковые атрибуты и в противном случае будут вести себя одинаково. Существует родительская модель, но она используется только в целях нормализации, и веб-пользователю никогда не нужно знать об этом. Что касается приложения, в нем есть типы сервисов и конкретные сервисы. Так что в основном я хочу, чтобы URL-адреса были такими:

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.

Есть идеи, что могло бы вызвать это?

В качестве вторичной проблемы я не могу найти способ включить вход в систему Webrat, чтобы увидеть, что на самом деле происходит HTTP-активность. Как я могу это сделать?

1 Ответ

0 голосов
/ 14 июня 2011

Да, неважно.Я идиот и забыл вставить render_views в мой тест , поэтому он не отображал представление .

...