Rails: Как изменить тесты для вложенного ресурса? - PullRequest
34 голосов
/ 20 сентября 2009

Во время изучения Rails я создал приложение с контроллером Domains, расположенным под контроллером Customers. Я использую Rails 2.3.4, и это был опыт обучения. Мне удалось настроить нижеприведенную маршрутизацию:

    customer_domains GET    /customers/:customer_id/domains(.:format)          {:controller=>"domains", :action=>"index"}
                     POST   /customers/:customer_id/domains(.:format)          {:controller=>"domains", :action=>"create"}
 new_customer_domain GET    /customers/:customer_id/domains/new(.:format)      {:controller=>"domains", :action=>"new"}
edit_customer_domain GET    /customers/:customer_id/domains/:id/edit(.:format) {:controller=>"domains", :action=>"edit"}
     customer_domain GET    /customers/:customer_id/domains/:id(.:format)      {:controller=>"domains", :action=>"show"}
                     PUT    /customers/:customer_id/domains/:id(.:format)      {:controller=>"domains", :action=>"update"}
                     DELETE /customers/:customer_id/domains/:id(.:format)      {:controller=>"domains", :action=>"destroy"}
           customers GET    /customers(.:format)                               {:controller=>"customers", :action=>"index"}
                     POST   /customers(.:format)                               {:controller=>"customers", :action=>"create"}
        new_customer GET    /customers/new(.:format)                           {:controller=>"customers", :action=>"new"}
       edit_customer GET    /customers/:id/edit(.:format)                      {:controller=>"customers", :action=>"edit"}
            customer GET    /customers/:id(.:format)                           {:controller=>"customers", :action=>"show"}
                     PUT    /customers/:id(.:format)                           {:controller=>"customers", :action=>"update"}
                     DELETE /customers/:id(.:format)                           {:controller=>"customers", :action=>"destroy"}
                root        /                                                  {:controller=>"customers", :action=>"index"}

Однако все тесты для контроллера доменов не пройдены из-за ошибок маршрутизации.

Например, следующий тест (сгенерированный генератором ресурсов Rails) завершается неудачно, как и все другие тесты в классе DomainsControllerTest.

class DomainsControllerTest < ActionController::TestCase
  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:domains)
  end
end

Сбой из-за ошибки:

No route matches {:action => "index", :controller => "domains"}

Это имеет смысл, поскольку маршруты по умолчанию больше не существуют, и для контроллера домена требуется установить @customer. Я провел целый день в поисках необходимых изменений, но почти каждый сайт говорит о тестах Rspec вместо обычных тестов Rails.

Как мне изменить domains_controller_test.rb, чтобы он понимал вложенный ресурс?

Ответы [ 3 ]

47 голосов
/ 20 сентября 2009

Передача customer_id с запросами сделает.Как то так: -

class DomainsControllerTest < ActionController::TestCase
  test "should get index" do
    get :index ,:customer_id=> 1
    assert_response :success
    assert_not_nil assigns(:domains)
  end
end
1 голос
/ 07 октября 2011

Существует камень под названием nester , который решает именно эту проблему. Он генерирует методы, которые возвращают вам domains_path и похожие, как если бы ваши маршруты не были вложенными. Когда ваши представления и тесты ссылаются, например, domain_path(domain), маршруты расширяются до customer_domain_path(domain.customer, domain). Существует также помощник ActionController::TestCase, который добавляет :customer_id => @domain.customer для таких методов, как get, post и т. Д.

При таком подходе сгенерированные функциональные тесты и представления по умолчанию работают из коробки. (Отказ от ответственности: я написал это.)

1 голос
/ 20 сентября 2009

Согласно вашим маршрутам, домены больше не существуют вне контекста клиента. Запрос должен customer_id для именованных маршрутов, чтобы соответствовать.

Способ сделать это в вашем тесте:

test "should get index" do
  get :index, :customer_id=>joe
end
...