Ответ 1
@request.host = 'user.myapp.com'
У меня есть приложение rails, которое действует по-разному в зависимости от того, к какой области он обратился (например, www.myapp.com будет ссылаться по-разному на user.myapp.com). В производстве это все работает отлично, но мой тестовый код всегда видит имя хоста "www.example.com".
Есть ли чистый способ проведения теста указать имя хоста, которое он притворяется для доступа?
@request.host = 'user.myapp.com'
Я думаю, что все ответы здесь неполные... Чтобы перечислить все возможные случаи:
Характеристики интеграции (наследующий от ActionDispatch::IntegrationTest
):
host! "my.awesome.host"
См. docs, раздел 5.1. Помощники, доступные для тестов интеграции.
Характеристики контроллера (наследующие от ActionController::TestCase
)
@request.host = 'my.awesome.host'
См. docs, раздел 4.4 Доступные переменные экземпляра.
Особенности функции (через Capybara)
Capybara.default_host = "http://my.awesome.host"
# Or to configure domain for route helpers:
default_url_options[:host] = "my.awesome.host"
Просмотр спецификаций (наследующий от ActionView::TestCase
)
@request.host = 'my.awesome.host'
... или через RSpec:
controller.request.host = "my.awesome.host"
См. rspec-rails
просмотр спецификаций.
В спецификациях функций, хост! устарел. Добавьте их в свой rspec_helper.rb:
# Configure Capybara expected host
Capybara.app_host = <myhost>
# Configure actual routes host during test
before(:each) do
default_url_options[:host] = <myhost>
end
Я считаю, что вы можете изменить классы окружения HTTP_HOST
или SERVER_NAME
, чтобы изменить запрос, поступающий на маршрутизатор:
ENV['SERVER_NAME'] = "user.myapp.com"
См. raw_host_with_port
в actionpack/lib/action_controller/request.rb.
Еще одна вещь, которую следует помнить, - убедиться, что вы используете правильный экземпляр сеанса, чтобы вы могли правильно инкапсулировать помощников URL.
Тесты интеграции предоставляют вам сеанс по умолчанию. Вы можете вызвать все методы сеанса непосредственно из ваших тестов
test "should integrate well" do
https!
get users_path
assert_response :success
end
Все эти помощники используют экземпляр сеанса по умолчанию, который, если он не изменен, переходит на "www.example.com". Как уже упоминалось, хост может быть изменен путем выполнения хоста! ( "My.new.host" )
Если вы создаете несколько сеансов с использованием метода open_session, вы должны ВСЕГДА использовать этот экземпляр для вызова вспомогательных методов. Это будет правильно инкапсулировать запрос. В противном случае рельсы вызовут экземпляр сеанса по умолчанию, который может использовать другой хост:
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
Для спецификаций запроса Rspec используйте before(:each) { host! 'example.com' }
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
@request.host = 'user.myapp.com'
неверен.
следует использовать host!('user.myapp.com')
Я пробовал много вариантов @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
Еще один ответ:
request.host = "user.myapp.com"
Я знаю, что это похоже на правильный ответ, но, пожалуйста, несите меня. Мне не нравится операция присваивания в тесте только для того, чтобы настроить ситуацию, я бы предпочел явный заглушку. Интересно, что такое укутывание не будет работать:
allow(request).to receive(:host).and_return("user.myapp.com")
Я лично предпочитаю укутывание по назначению, таким образом я получаю 2 преимущества, один из них заключается в том, что он будет проверен rspec проверять double, во-вторых, он явно говорит, что это заглушка, а не часть тестового упражнения.
Ни один из способов, предложенных в других ответах в этом пункте, не работал для меня. Это сработало:
Capybara.configure { |config| config.default_host = "my.domain.com" }