2011-09-03 4 views
15

Sono un po 'perplesso. Ho il seguente test di integrazione:Test delle risposte API REST con Rspec e Rack :: Test

require "spec_helper" 

describe "/foods", :type => :api do 
    include Rack::Test::Methods 

    let(:current_user) { create_user! } 
    let(:host) { "http://www.example.com" } 

    before do 
    login(current_user) 
    @food = FactoryGirl.create_list(:food, 10, :user => current_user) 
    end 

    context "viewing all foods owned by user" do 

    it "as JSON" do 
     get "/foods", :format => :json 

     foods_json = current_user.foods.to_json 
     last_response.body.should eql(foods_json) 
     last_response.status.should eql(200) 

     foods = JSON.parse(response.body) 

     foods.any? do |f| 
     f["food"]["user_id"] == current_user.id 
     end.should be_true 

     foods.any? do |f| 
     f["food"]["user_id"] != current_user.id 
     end.should be_false 
    end 

    end 

    context "creating a food item" do 

    it "returns successful JSON" do 
     food_item = FactoryGirl.create(:food, :user => current_user) 

     post "/foods.json", :food => food_item 

     food = current_user.foods.find_by_id(food_item["id"]) 
     route = "#{host}/foods/#{food.id}" 

     last_response.status.should eql(201) 
     last_response.headers["Location"].should eql(route) 
     last_response.body.should eql(food.to_json) 
    end 

    end 

end 

Ho aggiunto il rack desiderato :: Test :: Metodi per me ottenere il metodo last_response ma non sembra funzionare a destra. last_response sembra sempre di farmi vedere sign_in pagina anche se ho già effettuato.

Se rimuovo Rack :: Test :: Metodi last_response va via e posso usare response invece e ottengo la risposta corrente. Tutto sembra funzionare bene.

Perché è questo? Da dove viene il metodo response? Posso usare response per ottenere la risposta precedente dalla sessione?

ho bisogno di usare la last_response, o qualcosa di simile, per

last_response.headers["Location"].should eql(route) 

in modo che possa abbinare i percorsi. Se non fosse per questo sarei impostato.

+1

Qual è il codice per 'login' - è un metodo definito da rspec o lo hai definito altrove? La pagina di accesso richiede un reindirizzamento per funzionare? Se è così, metti "follow_redirect!" Dopo il codice di accesso. – iain

+0

Qual è la soluzione che ti è venuta in mente? Io lavoro anche con l'esempio [Ticketee] (https://github.com/rails3book/ticketee), ma ancora "last_response' non contiene la risposta che mi aspetto? Inoltre, non dimenticare di contrassegnare una delle risposte. – JJD

risposta

1

response è automatico per alcuni tipi di specifiche.

Rspec probabilmente miscela ActionController::TestCase::Behavior per :type => :api blocchi.
response verrebbe da ActionController::TestCase::Behavior, come per i blocchi :type => :controller.

Se si desidera ottenere la risposta prima di quella data da response, provare a memorizzarla in una variabile prima di effettuare la richiesta successiva.

https://www.relishapp.com/rspec/rspec-rails/v/2-3/docs/controller-specs e https://github.com/rspec/rspec-rails fornire alcune informazioni su ciò che è stato mescolato con alcuni dei vari tipi di specifiche.

+1

Ho avuto lo stesso problema, le mie specifiche non funzionavano quando le ho inserite in specifiche/controller, quando ho spostato le specifiche API in una cartella separata non ho ricevuto questo errore – shicholas

0

Penso che login(current_user) non funzioni con Rack :: Test :: Methods. Hai bisogno di un modo per autenticarti tramite la tua chiamata API, magari con un token di autenticazione.

response è collegato a ActionController, che conosce il tuo login. Se non sbaglio, le chiamate API sono indipendenti dal controller, quindi non sa che sei già connesso.

Vedere Ticketee, l'esempio di esempio da Rails 3 in Action, per un esempio!