2009-03-01 6 views
39

J'ai une application de rails qui agit différemment selon le domaine auquel elle est accédée (par exemple, www.myapp.com appellera différemment user.myapp.com). En production, tout cela fonctionne bien, mais mon code de test voit toujours un nom d'hôte de "www.example.com".Comment modifier le domaine "www.example.com" par défaut pour les tests dans les rails?

Existe-t-il une manière propre d'avoir un test spécifiant le nom d'hôte auquel il prétend accéder?

Répondre

23
@request.host = 'user.myapp.com' 
+17

'hôte! 'user.myapp.com'' a fonctionné pour moi – deb

+2

Dans une spécification de contrôleur, j'obtiens une erreur en essayant d'utiliser 'host!'. Définir '@ request.host' comme la réponse suggère travaillé cependant. –

+6

Et comment l'utiliser avec RSpec? Je veux dire, où puis-je le configurer? Merci beaucoup! – FRAGA

4

Je crois que vous pouvez modifier l'environnement HTTP_HOST ou SERVER_NAME vars changer la demande qui va au routeur:

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

Voir raw_host_with_port dans actionpack/lib/action_controller/request.rb.

1

@request.host = 'user.myapp.com' n'a pas raison. devrait utiliser host!('user.myapp.com')

+2

Cette syntaxe n'a pas fonctionné pour moi. La réponse acceptée non plus. La seule chose qui a fonctionné en tant qu'hôte! ('Newhostname.com'). – jeffarena

+1

Bien sûr, vous devez mettre la chaîne du nom d'hôte entre guillemets simples ou doubles. – justingordon

2

Une autre chose à retenir est de vous assurer d'utiliser l'instance de la session correcte afin que vous puissiez bien les aides d'encapsuler url.

Les tests d'intégration vous fournissent une session par défaut. Vous pouvez appeler all session methods directement à partir de vos tests

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

Toutes ces aides utilisent l'instance de session par défaut qui, si elle ne change pas, va à « www.example.com ». Comme cela a été mentionné, l'hôte peut être changé en faisant l'hôte! ("My.new.host")

Si vous créez plusieurs sessions en utilisant la méthode open_session, vous devez TOUJOURS utiliser cette instance pour appeler les méthodes d'assistance. Cela encapsulera correctement la demande. Dans le cas contraire rails appelleront 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 aviez l'intention d'utiliser l'objet de la session par défaut, vous devrez modifier cet hôte ainsi:

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 
9

Dans les spécifications des fonctionnalités, hôte! a été déprécié. 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 
+0

Note: Il semble que 'Capybara.app_host' doit inclure le protocole. Par exemple. '" http: //test.domain "' plutôt que simplement '" test.domain "'. – lime

+1

comment inclure le port? –

53

Je pense que toutes les réponses sont incomplètes ici ... Pour énumérer tous les cas possibles:

  • intégration Spécifications (héritant de ActionDispatch::IntegrationTest):

    host! "my.awesome.host" 
    

    Voir le docs, section 5.1 Aides disponibles pour les tests d'intégration.

  • contrôleur Spécifications (héritant de ActionController::TestCase)

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

    Voir la docs, l'article 4.4 Variables d'instance disponibles.

  • Caractéristiques Spécs (par Capybara)

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

    De @AminAriana's answer

  • Voir caractéristiques (héritant de ActionView::TestCase)

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

    ... ou par RSpec:

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

    Voir la rspec-railsview spec docs.

+0

Grâce aux rails 5 et en passant de 'ActionController :: TestCase' à' ActionDispatch :: IntegrationTest', cette 'Spécification d'intégration' est inestimable pour ceux d'entre nous qui ont déjà des applications multi-tennant.C'était la première réponse qui montrait comment obtenir '@ request.host' en une suite plus ancienne (en utilisant' host! '). En lisant les docs, cela ne m'a pas échappé, mais nous y voilà, et merci! – pjammer

1

J'ai essayé beaucoup de variations de @request.host, host! et post path, args, {'SERVER_NAME' => my_secret_domain} sans succès, à la fois que les tests du régulateur et des tests de fonction. Très agaçant, comme tant d'autres ont rapporté le succès avec ces approches.

La solution pour moi était:

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

Je suis en rubis 2.1.5p273, rspec 3.1.7 et 4.2.0 Rails

0

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, je suis nue avec moi. Je n'aime pas l'opération d'assignation en test juste pour mettre les choses en place, je préférerais un talon explicite. Fait intéressant, stubbing comme cette ne sera pas travail:

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

Je préfère personnellement stubbing sur l'affectation, de cette façon que je reçois deux avantages, l'un est qu'il sera validé par rspec Vérifions à double, la deuxième est que il est explicitement dit que c'est un bout, pas une partie de l'exercice d'essai.

0

Aucun des moyens suggérés dans d'autres réponses au point travaillé pour moi. Cela a fonctionné:

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