Sto lavorando a un'applicazione che verrà utilizzata principalmente come API (a parte alcune visualizzazioni minori, come sessione/registrazione, che saranno "standard"). Mi piace l'approccio che è stato finalizzato in Railscast #350: Versioning an API, quindi l'ho seguito. I miei percorsi assomigliano:Come verificare i vincoli del percorso con rspec
namespace :api, :defaults => {:format => 'json'} do
scope :module => :v1, :constraints => ApiConstraints.new(:version => 1, :default => false) do
resources :posts, :only => [:create, :show, :destroy, :index]
end
scope :module => :v2, :constraints => ApiConstraints.new(:version => 2, :default => true) do
resources :posts, :only => [:create, :show, :destroy, :index]
end
end
In ogni percorso, il mio vincolo è un nuovo ApiConstraints oggetto, che si trova nella mia cartella ./lib
. La classe è simile al seguente:
class ApiConstraints
def initialize(options)
@version = options[:version]
@default = options[:default]
end
def matches?(req)
@default || req.headers['Accept'].include?("application/vnd.MYAPP.v#{@version}")
end
end
Ora, durante il test manuale, tutto funziona come previsto. Nella mia API, potrei avere tra 5 e 10 controllori per versione e non voglio testare che i vincoli dell'API funzionino per ogni singolo controller, poiché ciò non ha senso. Sto cercando un file spec che metta alla prova i miei vincoli API, ma non sono sicuro di dove mettere le specifiche.
Ho provato ad aggiungere un file spec/routing/api_spec.rb
per verificare le cose, ma non sta funzionando correttamente, come si lamenta che alcune cose non sono forniti, in questo modo:
it "should route an unversioned request to the latest version" do
expect(:get => "/api/posts", :format => "json").to route_to(:controller => "api/v1/posts")
end
È possibile che questo genera un errore, anche se il controller corrisponde correttamente. Viene a mancare con il seguente errore:
The recognized options <{"format"=>"json", "action"=>"index", "controller"=>"api/v1/posts"}>
did not match <{"controller"=>"api/v1/posts"}>,
difference: <{"format"=>"json", "action"=>"index"}>.
Si noti che il controller è stato correttamente determinato, ma dal momento che non voglio mettere alla prova per il formato e l'azione in questo test, esso errori fuori. Vorrei ci fosse 3 "specifiche API":
- Dovrebbe percorso una richiesta sotto controllo di versione alla versione più recente
- Va default il formato JSON, se non viene specificato
- Dovrebbe restituire un determinato Versione API quando richiesto
Qualcuno ha esperienza con le specifiche di scrittura per questo tipo di percorsi? Non voglio aggiungere specifiche per ogni controller all'interno dell'API, in quanto non sono responsabili di questa funzionalità.
Sì, questo è corretto. Idealmente, voglio tre test nel mio file spec api, uno per verificare che funzioni il formato predefinito, uno per verificare che instradi a un controller valido quando non è specificata alcuna versione e uno per verificare che instradi alla versione corretta quando versione IS specificata. –
Bene, usando 'route_to' è necessario fornire aspettative più specifiche, come' expect (: get => "/api/posts.json"').to route_to (: controller =>" api/v1/posts ",: action => "index",: format => "json") '. Sfortunatamente non c'è modo di aggirarlo con gli abbinamenti rspec-rails predefiniti. – gregates
Il problema è che ogni specifica testerà la logica da ogni altra specifica. Sta essenzialmente facendo rotolare tutte le specifiche in un test, il che non è l'ideale. –