Подтвердить что ты не робот

Проверка Rails на наличие промежуточного ПО Rack за пределами внутренней сети Rails

Контекст: приложение использует часть промежуточного программного обеспечения для стойки, которое должно настраиваться в config.ru, а не на внутренней промежуточной цепочке Rails. Это по причинам, не имеющим отношения к этому вопросу.

Вопрос: как мне сделать мои тесты (функциональные и интеграционные) об этом промежуточном программном обеспечении?

Я воспользуюсь примером. Позвольте создать нетронутое приложение Rails 3, используя rack-rewrite для иллюстрации.

# /config/initializers/example.rb
Rails.application.middleware.insert 0, 'Rack::Rewrite' do
 r301 '/so', 'http://stackoverflow.com'
end

# /test/integration/the_test.rb
require 'test_helper'

class TheTest < ActionDispatch::IntegrationTest
 test "redirect from /so to http://stackoverflow.com" do
   get '/so'
   assert_redirected_to 'http://stackoverflow.com'
 end
end

Если вы выполните вышеуказанный тест, все будет хорошо, и в браузере вы можете подтвердить, что посещение пути /so действительно перенаправит вас на StackOverflow.

Прохладный, давайте теперь настроим это вне Rails. Удалите файл /config/initializers/example.rb, описанный выше, и измените config.ru на следующее:

# /config.ru
require ::File.expand_path('../config/environment',  __FILE__)

map '/so' do
  run Rack::Rewrite do
    r301 '', 'http://stackoverflow.com'
  end
end

map '/' do
  run Deleteme::Application
end

Теперь тест перестанет работать. Функциональность действительно работает, о чем свидетельствует, если вы посещаете /so в своем браузере. Это только то, что тесты не знают об установке Rack.

4b9b3361

Ответ 1

(Спасибо Dan Croak за то, что он меня на правильном пути. Этот ответ завершает то, что он сказал).

Короткий ответ

Невозможно выполнить функциональные тесты.

Для тестов интеграции добавьте следующее к test_helper.rb:

ActionDispatch::IntegrationTest.app = Rack::Builder.new do
  eval File.read(Rails.root.join('config.ru'))
end

Длинный ответ

Функциональные тесты - это всего лишь единичные тесты, выполняемые с контроллерами. Когда вы говорите, например get :index, вы не разрешаете маршрут. Вместо этого это сокращение для вызова метода index, с окружением запроса, которое включает упоминание HTTP-метода GET.

Следовательно, имеет смысл, что ваш стек стека не влияет на функциональные тесты.

Интеграционные тесты - это другое дело. Вы тестируете свой полный стек там, поэтому вы захотите также проверить свои средние очки в стойке. Единственная проблема заключается в том, что по умолчанию эти тесты показывают только средние продукты, которые вы добавляете, используя собственный API Rails.

Но я говорю "по умолчанию", потому что Rails предлагает способ изменить то, что будет проверен стек стека. По умолчанию интеграционные тесты вызывают Rails.application для своих запросов. Вы можете изменить это на все, что соответствует вашим потребностям.

Используя приведенный выше код, мы используем Rack::Builder создать ad-hoc Rack application. Внутри блока вы можете поместить любой код, который вы обычно помещаете в файл config.ru. Чтобы избежать дублирования кода, eval загружает наш config.ru файл. Теперь наши интеграционные тесты будут загружать точно такое же приложение, что и наши серверы приложений.

Ответ 2

Я думаю, проблема в том, что ActionDispatch::IntegrationTest использует ваш Rails.application как приложение Rack для теста.

Итак, если вы можете обернуть это правило Rack::Rewrite в некоторое промежуточное ПО Rack, вы сможете переопределить приложение Rack, которое вы тестируете в своем тесте, с помощью

ActionDispatch::IntegrationTest.app = MyRewriteMiddleware