J'ai une application Rails qui agit différemment en fonction du domaine auquel l'accès est effectué (par exemple, www.myapp.com invoquera différemment utilisateur.monapp.com). En production, tout fonctionne bien, mais mon code de test voit toujours un nom d’hôte "www.example.com".
Existe-t-il un moyen propre d’avoir un test pour spécifier le nom d’hôte auquel il prétend accéder?
@request.Host = 'user.myapp.com'
Je pense que toutes les réponses sont incomplètes ici ... Pour énumérer tous les cas possibles:
Integration Specs (héritant de ActionDispatch::IntegrationTest
):
Host! "my.awesome.Host"
Voir les docs , section 5.1 Aide disponible pour les tests d'intégration.
Controller Specs (héritant de ActionController::TestCase
)
@request.Host = 'my.awesome.Host'
Voir les docs , section 4.4 Variables d'instance disponibles.
Caractéristiques techniques (via Capybara)
Capybara.default_Host = "http://my.awesome.Host"
# Or to configure domain for route helpers:
default_url_options[:Host] = "my.awesome.Host"
View Specs (héritant de ActionView::TestCase
)
@request.Host = 'my.awesome.Host'
... ou via RSpec:
controller.request.Host = "my.awesome.Host"
Voir le rspec-Rails
view spec docs .
Dans les caractéristiques techniques, hôte! a été déconseillé. Ajoutez-les à votre 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
Une autre chose à retenir est de veiller à utiliser l'instance de session correct afin de pouvoir encapsuler correctement les aides URL.
Les tests d'intégration vous fournissent une session par défaut. Vous pouvez appeler toutes les méthodes de session directement à partir de vos tests
test "should integrate well" do
https!
get users_path
assert_response :success
end
Tous ces assistants utilisent l'instance de session par défaut, qui, si elle n'est pas modifiée, va à "www.example.com". Comme cela a été mentionné, l'hôte peut être modifié en faisant hôte! ("My.new.Host")
Si vous créez plusieurs sessions à l'aide de la méthode open_session, vous devez TOUJOURS utiliser cette instance pour appeler les méthodes d'assistance. Cela encapsulera correctement la demande. Sinon, Rails appellera l'instance de session par défaut qui peut utiliser un hôte différent:
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
Si vous souhaitez utiliser l'objet de session par défaut, vous devez également modifier cet hôte:
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
Pour les spécifications de demande Rspec, utilisez before(:each) { Host! 'example.com' }
Voir plus à: https://relishapp.com/rspec/rspec-Rails/v/3-6/docs/request-specs/request-spechttps: // github .com/rspec/rspec-Rails/issues/1662 # issuecomment-241201056
Je pense que vous pouvez modifier les vars d'environnement HTTP_Host
ou SERVER_NAME
pour modifier la demande adressée au routeur:
ENV['SERVER_NAME'] = "user.myapp.com"
Voir raw_Host_with_port
dans actionpack/lib/action_controller/request.rb .
@request.Host = 'user.myapp.com'
n'est pas correct ..__ devrait utiliser Host!('user.myapp.com')
J'ai essayé plusieurs variantes de @request.Host
, Host!
et post path, args, {'SERVER_NAME' => my_secret_domain}
sans succès, à la fois comme tests de contrôleur et de tests de fonctionnalités. Très aggravant, comme tant d'autres ont rapporté le succès de ces approches.
La solution pour moi était:
request.headers["SERVER_NAME"] = my_secret_domain
post path, args
J'utilise Ruby 2.1.5p273, rspec 3.1.7 et Rails 4.2.0
Aucune des manières suggérées dans les autres réponses au point n'a fonctionné pour moi. Cela a fonctionné:
Capybara.configure { |config| config.default_Host = "my.domain.com" }
Encore une autre réponse:
request.Host = "user.myapp.com"
Je sais que cela ressemble à la bonne réponse, mais s'il vous plaît, supportez-moi. Je n'aime pas l'opération d'assignation dans le test juste pour configurer les choses, je préférerais un stub explicite. Fait intéressant, stubbing comme ceci ne sera pas travail:
allow(request).to receive(:Host).and_return("user.myapp.com")
Personnellement, je préfère le remplacement par assignation, de cette façon, je reçois deux avantages: l’un est qu’il sera validé par rspec vérifie double , ensuite, il indique explicitement qu’il s’agit d’un talon qui ne fait pas partie de l’exercice de test.