#ruby-on-rails
#ruby-on-rails
Вопрос:
Я работаю над устаревшим проектом Rails 2. У меня MyController
в Foo
модуле:
module Api::Foo
class MyController < ::ActionController::Base
def doJob
puts "do the job"
end
end
end
В routes.rb у меня есть:
map.connect 'api/foo/dojob', :controller => 'api/foo/my',:action => 'doJob', :conditions => { :method => :post }
У меня есть другой контроллер, который находится вне Foo
модуля, он находится в Bar
модуле:
module Api::Bar
class AnotherController < ::ActionController::Base
def doCalculation
puts "do the calculation"
end
end
end
В модульном тестировании AnotherControllerTest
, как я могу отправить в конечную api/foo/dojob
точку?
class Api::Bar::AnotherControllerTest < ActionController::TestCase
def setup
end
test 'test internal api call' do
# how to post to "api/foo/dojob"??
end
end
Я пробовал post "/api/foo/dojob",{}
, это не работает.
Комментарии:
1. зачем вам это делать?. Контроллеры не должны вызывать код других контроллеров. Если вам нужен код из одного контроллера в другом, затем извлеките его в
module
orclass
.
Ответ №1:
Вы не можете. ActionController::TestCase
абстрагирует весь этап фактического выполнения фактического HTTP-запроса.
Что ActionController::TestCase
происходит, когда вы делаете get :foo
, это создаете экземпляр Api::Bar::AnotherController
и передаете ему mocked request . Затем он вызывает #foo
метод на контроллере. В то время все это казалось отличной идеей, поскольку позволяло вам копаться во внутренних элементах контроллеров и было немного быстрее.
Он выводит класс из имени класса тестового примера. Хотя вы могли бы переопределить это для создания экземпляра какого-либо другого контроллера, это неправильный ответ на неправильную проблему. Вся идея модульного теста заключается в том, что он тестирует один компонент изолированно.
Для проведения интеграционного тестирования, при котором вы тестируете несколько контроллеров, вам нужен ActionController::IntegrationTest. Интеграционный тест фактически отправляет HTTP-запрос на тестовый сервер. Это также более перспективная стратегия тестирования, поскольку тесты контроллера были отменены.
require 'test_helper'
class ApiFlowsTest < ActionController::IntegrationTest
def setup
end
test 'test internal api call' do
post "api/foo/dojob", { foo: 'bar' }
get "api/foo/bar"
assert_response :success
end
end
Комментарии:
1. Кстати, сама идея модульного тестирования контроллеров была глубоко ошибочной и очень сильно вышла из моды в мире rails.