Как вызвать именованный маршрут Rails при тестировании контроллеров с RSpec?

#ruby-on-rails #ruby #rspec #rspec-rails #ruby-on-rails-2

#ruby-on-rails #ruby #rspec #rspec-rails #ruby-on-rails-2

Вопрос:

Я хочу протестировать действие постоянной ссылки в моем контроллере articles, который использует именованный маршрут (/ permalink/terms-of-use):

 map.permalink 'permalink/:permalink', 
              :controller => :articles, :action => :permalink, :as => :permalink
  

Это спецификация:

 describe "GET permalink" do
  it "should visit an article" do
    get "/permalink/@article.permalink"
  end
end
  

Но я получаю эту ошибку:

ActionController::RoutingError в ‘Постоянная ссылка ArticlesController отображает страницу’ Маршрут не соответствует {:controller=>»статьи», :action=>»/permalink/@article.permalink «}

Обновить:

есть идеи, как написать GET?

Ответ №1:

Ошибка заключается в том, что вы передаете весь URL-адрес методу, который ожидает имя одного из методов действия контроллера. Если я правильно понимаю, вы пытаетесь протестировать несколько вещей одновременно.

Проверка того, что у маршрута есть имя, отличается от тестирования маршрута, отличающегося от тестирования действия контроллера. Вот как я тестирую действие контроллера (вероятно, это неудивительно). Обратите внимание, что я сопоставляю ваше имя, а не рекомендую то, что бы я использовал.

В спецификации / controllers/article_controller_spec.rb,

 describe ArticlesController do
  describe '#permalink' do
    it "renders the page" do
      # The action and its parameter are both named permalink
      get :permalink :permalink => 666
      response.should be_success
      # etc.
    end
  end
end
  

Вот как я тестирую именованный маршрут только с rspec-rails:

В спецификации / маршрутизации/article_routing_spec.rb,

 describe ArticlesController do
  describe 'permalink' do

    it 'has a named route' do
      articles_permalink(666).should == '/permalink/666'
    end

    it 'is routed to' do
      { :get => '/permalink/666' }.should route_to(
        :controller => 'articles', :action => 'permalink', :id => '666')
    end

  end
end
  

Сопоставитель маршрутов Shoulda более лаконичен, но при этом предоставляет хорошее описание и сообщение об ошибке:

 describe ArticlesController do
  describe 'permalink' do

    it 'has a named route' do
      articles_permalink(666).should == '/permalink/666'
    end

    it { should route(:get, '/permalink/666').to(
      :controller => 'articles', :action => 'permalink', :id => '666' })

  end
end
  

AFAIK, ни у RSpec, ни у Shoulda не должно быть конкретного, сжатого способа тестирования именованных маршрутов, но вы могли бы написать свой собственный механизм сопоставления.

Комментарии:

1. в нашем первом примере я получаю ошибку маршрутизации, мне нужно протестировать ‘permalink / a_name’. Извините, мой вопрос был неясен. Мне нужно протестировать действие постоянной ссылки, но я использую именованный маршрут. Мне нужно знать правильный синтаксис get …

2. Когда вы тестируете действие, не беспокойтесь о его маршруте. Просто протестируйте действие напрямую, как в первом примере кода выше. Тестирование маршрута — это другая проблема; смотрите два других примера для этого.

3. ваш первый пример не работает, потому что создается get, содержащий статьи в URL, т. Е. /articles/permalink/name_of_article, но мне нужна /permalink/name_of_the_article, а RSpec не позволяет мне этого сделать.

4. Я скорректировал свои примеры, чтобы они соответствовали тому, что, как мне кажется, вы пытаетесь сделать. Однако важным моментом является не специфика маршрута, а разница между тестированием действия и тестированием маршрута. В тестировании контроллера RSpec первым параметром get является имя действия, а не путь. Предоставьте остальную информацию в пути, используя параметры.

5. Ваш первый пример очень похож на мой тест, но он выдает: ActionController::RoutingError в ‘ArticlesController GET permalink отображает страницу’ Маршрут не соответствует {:controller=>»статьи», :permalink=>»ссылка», :action=> «постоянная ссылка»}

Ответ №2:

 describe "GET permalink" do
  it "should visit an article" do
    get "/permalink/#{@article.permalink}"
  end
end
  

Комментарии:

1. Нет. Я получаю это: ActionController::RoutingError в ‘ArticlesController, ПОЛУЧАЮЩИЙ постоянную ссылку, должен посетить статью’ Маршрут не совпадает {:controller=>»статьи», :action=>»/ permalink/ link»}