Как изменить домен www.example.com по умолчанию для тестирования в рельсах?

У меня есть приложение rails, которое действует по-разному в зависимости от того, к какому домену он обращается (например, www.myapp.com будет по-разному вызывать user.myapp.com). В производственной среде все работает нормально, но мой тестовый код всегда видит имя хоста «www.example.com».

Есть ли чистый способ указать в тесте имя хоста, к которому он пытается получить доступ?

Ответов (10)

Решение
@request.host = 'user.myapp.com'

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

Интеграционные тесты предоставляют вам сеанс по умолчанию. Вы можете вызывать все методы сеанса прямо из ваших тестов

test "should integrate well" do
  https!
  get users_path
  assert_response :success
end

Все эти помощники используют экземпляр сеанса по умолчанию, который, если его не изменить, переходит на «www.example.com». Как уже упоминалось, хост можно изменить, выполнив команду host! ("My.new.host")

Если вы создаете несколько сеансов с помощью метода open_session, вы должны ВСЕГДА использовать этот экземпляр для вызова вспомогательных методов. Это правильно инкапсулирует запрос. В противном случае rails вызовет экземпляр сеанса по умолчанию, который может использовать другой хост:

test "should integrate well" do
  sess = open_session
  sess.host! "my.awesome.host"
  sess.get users_url             #=> WRONG! will use default session object to build url.
  sess.get sess.users_url        #=> Correctly invoking url writer from my custom session with new host.
  sess.assert_response :success
end

Если вы намеревались использовать объект сеанса по умолчанию, вам также придется изменить этот хост:

test "should integrate well" do
  sess = open_session
  sess.host! "my.awesome.host"
  host! sess.host              #=> Set default session host to my custom session host.
  sess.get users_url
end 

Я пробовал много вариантов @request.host, host! и post path, args, {'SERVER_NAME' => my_secret_domain} без успеха, так как тесты контроллеров и художественных тесты. Это очень обидно, так как многие другие сообщили об успехе этих подходов.

Решение для меня было:

request.headers["SERVER_NAME"] = my_secret_domain
post path, args

Я использую ruby ​​2.1.5p273, rspec 3.1.7 и Rails 4.2.0

Характеристики функций

В спецификациях функций host! устарел. Добавьте их в свой spec_helper.rb :

# Configure Capybara expected host
Capybara.app_host = "http://test.domain"

# Configure actual routes host during test
before(:each) do
  default_url_options[:host] = <myhost>
end

Запросить спецификации

В спецификациях запроса продолжайте использовать host! :

host! "test.domain"

В качестве альтернативы реорганизуйте его в before(:each) блоках или настройте глобально для спецификации запроса на spec_helper.rb уровне:

RSpec.configure do |config|
  config.before(:each, type: :request) do
    host! "test.domain"
  end
end

Еще один ответ:

request.host = "user.myapp.com"

Я знаю, что это похоже на правильный ответ, но, пожалуйста, потерпите меня. Мне не нравится операция присваивания в тесте только для настройки, я бы предпочел явную заглушку. Интересно, что такие заглушки не работают:

allow(request).to receive(:host).and_return("user.myapp.com")

Я лично предпочитаю заглушку присваиванию, так что я получаю 2 преимущества: во- первых , он будет проверен с помощью rspec verify double , во-вторых, он явно говорит, что это заглушка, а не часть тестового упражнения.

Для спецификаций запроса Rspec используйте before(:each) { host! 'example.com' }

Подробнее см. https://relishapp.com/rspec/rspec-rails/v/3-6/docs/request-specs/request-spec https://github.com/rspec/rspec-rails/issues/1662 # issuecomment-241201056

Я считаю, что вы можете изменить переменные среды HTTP_HOST или, SERVER_NAME чтобы изменить запрос, отправляемый маршрутизатору:

ENV['SERVER_NAME'] = "user.myapp.com"

Смотрите raw_host_with_port в actionpack / lib / action_controller / request.rb .

@request.host = 'user.myapp.com' это не правильно. следует использовать host!('user.myapp.com')

Ни один из способов, предложенных в других ответах на тот момент, не помог мне. Это сработало:

Capybara.configure { |config| config.default_host = "my.domain.com" }

Думаю, здесь все ответы неполные ... Перечислим все возможные случаи:

  • Спецификации интеграции (наследуются от ActionDispatch::IntegrationTest):

    host! "my.awesome.host"
    

    См. Документацию в разделе 5.1 Помощники, доступные для интеграционных тестов .

  • Спецификации контроллера (наследуются от ActionController::TestCase)

    @request.host = 'my.awesome.host'
    

    См. Документацию в разделе 4.4 Доступные переменные экземпляра .

  • Характеристики функций (через Capybara)

    Capybara.default_host = "http://my.awesome.host"
    # Or to configure domain for route helpers:
    default_url_options[:host] = "my.awesome.host"
    

    Из ответа @AminAriana

  • Просмотр спецификаций (наследуемый от ActionView::TestCase)

    @request.host = 'my.awesome.host'
    

    ... или через RSpec:

    controller.request.host = "my.awesome.host"
    

    См. rspec-rails Документацию по спецификациям просмотра .