Ich habe eine Rails-Anwendung, die je nach Domain, auf die zugegriffen wird, unterschiedlich funktioniert (zum Beispiel wird www.myapp.com anders als user.myapp.com aufgerufen). In der Produktion funktioniert dies alles einwandfrei, aber in meinem Testcode wird immer der Hostname "www.example.com" angezeigt.
Gibt es eine saubere Möglichkeit, einen Test den Hostnamen angeben zu lassen, auf den er vorgeben soll zuzugreifen?
@request.Host = 'user.myapp.com'
Ich denke, dass alle Antworten hier unvollständig sind ... Um alle möglichen Fälle aufzuzählen:
Integrationsspezifikationen (erbt von ActionDispatch::IntegrationTest
):
Host! "my.awesome.Host"
Siehe docs , Abschnitt 5.1 Verfügbare Helfer für Integrationstests.
Controller Specs (erbt von ActionController::TestCase
)
@request.Host = 'my.awesome.Host'
Siehe docs , Abschnitt 4.4 Instanzvariablen verfügbar.
Feature Specs (über Capybara)
Capybara.default_Host = "http://my.awesome.Host"
# Or to configure domain for route helpers:
default_url_options[:Host] = "my.awesome.Host"
View Specs (erbt von ActionView::TestCase
)
@request.Host = 'my.awesome.Host'
... oder über RSpec:
controller.request.Host = "my.awesome.Host"
Siehe rspec-Rails
view spec docs .
In Feature-Spezifikationen, Host! wurde nicht mehr empfohlen. Fügen Sie diese zu Ihrer rspec_helper.rb hinzu:
# Configure Capybara expected Host
Capybara.app_Host = <myhost>
# Configure actual routes Host during test
before(:each) do
default_url_options[:Host] = <myhost>
end
Beachten Sie außerdem, dass Sie die korrekte Session-Instanz verwenden, damit Sie die URL-Helfer korrekt kapseln können.
Integrationstests bieten Ihnen eine Standardsitzung. Sie können alle Sitzungsmethoden direkt aus Ihren Tests aufrufen
test "should integrate well" do
https!
get users_path
assert_response :success
end
Alle diese Helfer verwenden die Standardsitzungsinstanz, die, wenn sie nicht geändert wird, zu "www.example.com" wechselt. Wie bereits erwähnt, kann der Host durch Ausführen von Host! ("My.new.Host") geändert werden.
Wenn Sie mehrere Sitzungen mit der Methode open_session erstellen, müssen Sie IMMER diese Instanz verwenden, um die Hilfsmethoden aufzurufen. Dadurch wird die Anforderung ordnungsgemäß gekapselt. Andernfalls ruft Rails die Standardsitzungsinstanz auf, die möglicherweise einen anderen Host verwendet:
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
Wenn Sie das Standardsitzungsobjekt verwenden möchten, müssen Sie auch diesen Host ändern:
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
Für Rspec-Anforderungsspezifikationen verwenden Sie before(:each) { Host! 'example.com' }
.
Weitere Informationen finden Sie unter: https://relishapp.com/rspec/rspec-Rails/v/3-6/docs/request-specs/request-spechttps : //github.com/rspec/rspec-Rails/issues/1662#issuecomment-241201056
Ich glaube, Sie können die Umgebungsvariablen HTTP_Host
oder SERVER_NAME
ändern, um die Anforderung zu ändern, die an den Router gesendet wird:
ENV['SERVER_NAME'] = "user.myapp.com"
Siehe raw_Host_with_port
in actionpack/lib/action_controller/request.rb .
@request.Host = 'user.myapp.com'
ist nicht richtig. sollte Host!('user.myapp.com')
verwenden.
Ich habe viele Variationen von @request.Host
, Host!
und post path, args, {'SERVER_NAME' => my_secret_domain}
ohne Erfolg ausprobiert, sowohl als Controller-Tests als auch für Feature-Tests. Sehr ärgerlich, da so viele andere mit diesen Ansätzen von Erfolg berichten.
Die Lösung für mich war:
request.headers["SERVER_NAME"] = my_secret_domain
post path, args
Ich verwende Ruby 2.1.5p273, rspec 3.1.7 und Rails 4.2.0
Keine der in anderen Antworten vorgeschlagenen Möglichkeiten funktionierte für mich. Das hat funktioniert:
Capybara.configure { |config| config.default_Host = "my.domain.com" }
Noch eine Antwort:
request.Host = "user.myapp.com"
Ich weiß, dass es der richtigen Antwort ähnelt, aber bitte halten Sie sich bei mir. Ich mag die Zuweisungsoperation im Test nicht, nur um Dinge einzurichten, ich würde einen expliziten Stub vorziehen. Interessanterweise wird das Stubbing wie folgt wird nicht funktionieren:
allow(request).to receive(:Host).and_return("user.myapp.com")
Ich persönlich bevorzuge Stubbing gegenüber Zuweisung, auf diese Weise bekomme ich 2 Vorteile, einer ist, dass es durch rspecs Verify Double validiert wird. Zweitens heißt es ausdrücklich, dass es sich um einen Stub handelt, der nicht Teil der Testübung ist.