Wie Schreibe ich eine Rails 3.1 engine-controller-test von rspec?
Ich geschrieben habe eine Rails 3.1 Motor mit dem namespace-Beiträge. Daher mein Controller findet sich in app/controllers/posts/, meine Modelle in app/models/posts, etc. Ich kann testen Sie die Modelle ganz gut. Die Skillung für ein Modell sieht aus wie...
module Posts
describe Post do
describe 'Associations' do
it ...
end
... und alles funktioniert.
Jedoch die Spezifikationen für die Controller funktionieren nicht. Die Schienen-Motor ist montiert auf /posts, aber der controller Beiträge::PostController. So, die tests sehen für den controller route Beiträge/posts.
describe "GET index" do
it "assigns all posts as @posts" do
Posts::Post.stub(:all) { [mock_post] }
get :index
assigns(:posts).should eq([mock_post])
end
end
ergibt...
1) Posts::PostsController GET index assigns all posts as @posts
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"posts/posts"}
# ./spec/controllers/posts/posts_controller_spec.rb:16
Ich habe versucht, alle Arten von tricks in der test-app die Routen-Datei... : - namespace, etc, ohne Erfolg.
Wie mache ich diese Arbeit? Es scheint, wie es nicht, da der Motor versetzt den controller auf /posts, noch die Namensräume legt den controller auf /posts/Beiträge mit dem Zweck der Prüfung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin davon ausgegangen, dass Sie testen Ihren Motor mit einer dummy rails-app, wie die, die hervorgebracht werden durch enginex.
Ihren Motor montiert werden soll, in die dummy-app:
In
spec/dummy/config/routes.rb
:Meine zweite Annahme ist, dass Ihr Motor isoliert ist:
In
lib/posts.rb
:Ich weiß nicht, ob diese beiden Annahmen sind wirklich erforderlich, aber das ist, wie mein Motor aufgebaut ist.
Die Abhilfe ist ganz einfach, statt diese
verwenden Sie diese
Den
:posts
symbol sollte der name Ihres Motors und NICHT den Pfad, in dem es montiert ist.Dies funktioniert, da die get-Methode Parameter übergeben werden gerade zu
ActionDispatch::Routing::RouteSet::Generator#initialize
(definiert hier), die wiederum verwendet@named_route
um die korrekte route vonRack::Mount::RouteSet#generate
(siehe hier und hier).Eintauchen in die rails-Interna ist lustig, aber ziemlich zeitaufwändig, würde ich nicht tun, das jeden Tag 😉 .
HTH
before(:each) { @routes = Posts::Engine.routes }
. Fand es hier: stackoverflow.com/a/8140626/299781Ich arbeitete um dieses Problem durch überschreiben der
get
,post
,put
, unddelete
Methoden, die bereitgestellt werden, machen es so dass Sie immer passenuse_route
als parameter.Ich verwendet Benoit Antwort als Grundlage für diese. Dank buddy!
Verwenden Sie die rspec-rails
routes
Richtlinie:– RSpec-Rails 2.14 offiziellen docs.
Basierend auf diese Antwort ich entschied mich für die folgende Lösung:
Den zusätzlichen Vorteil ist, dass Sie nicht brauchen, um die
before(:each)
block in jeder controller-spec.Lösung für ein problem, wenn Sie nicht haben oder nicht nutzen
isolate_namespace
:Controller-Spezifikationen, beheben Strecken:
Schienen fügt _engine zu Ihrer app zu Routen, wenn Sie nicht verwenden
isolate_namespace
.Entwickle ich ein Juwel für meine Firma, bietet eine API für die Anwendungen, die wir ausführen. Wir sind mit Rails 3.0.9 immer noch, mit der neuesten Rspec-Rails (2.10.1). Ich hatte ein ähnliches Problem, wo ich den vorgegebenen Routen wie so in meine Rails-Motor gem.
War ich immer eine Fehlermeldung wie
Es stellt sich heraus, ich brauchte nur neu zu definieren, meine route in Unterstrich Fall so, dass RSpec, könnte es passen.
Ich denke, Rspec controller tests verwenden Sie einen reverse-lookup auf Basis Unterstrich Fall, in der Erwägung, dass Rails setup und interpretieren Sie die route, wenn Sie es definieren in camelcase oder Unterstrich Fall.