2011-09-03 11 views
15

Estoy un poco perplejo. Tengo la siguiente prueba de integración:Probando respuestas REST-API con Rspec y 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 

He añadido el bastidor requerida :: Test :: Métodos para conseguirme el método last_response pero no parece funcionar bien. last_response siempre me parece mostrar la página sign_in a pesar de que ya he iniciado sesión.

Si quito rack :: Test :: Métodos last_response desaparece y puedo usar response lugar y obtener la respuesta actual. Todo parece funcionar bien

¿Por qué es esto? ¿De dónde viene el método response? ¿Puedo usar response para obtener la respuesta anterior de la sesión?

Tengo que utilizar el last_response, o algo similar, para

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

para que pueda coincidir con las rutas. Si no fuera por esto, estaría listo.

+1

¿Cuál es el código de 'login' - es un método definido por rspec o lo definió en otro lugar? ¿La página de inicio de sesión requiere una redirección para funcionar? Si es así, ponga 'follow_redirect!' Después del código de inicio de sesión. – iain

+0

¿Cuál es la solución que se le ocurrió? Trabajo también con el ejemplo de [Ticketee] (https://github.com/rails3book/ticketee) pero todavía 'last_response' no contiene la respuesta que espero? Además, no te olvides de marcar una de las respuestas. – JJD

Respuesta

1

response es automático para ciertos tipos de especificaciones.

Rspec probablemente mezcle ActionController::TestCase::Behavior para :type => :api bloques.
response vendría de ActionController::TestCase::Behavior, como lo hace para :type => :controller bloques.

Si desea obtener la respuesta anterior a la dada por response, intente almacenarla en una variable antes de realizar la próxima solicitud.

https://www.relishapp.com/rspec/rspec-rails/v/2-3/docs/controller-specs y https://github.com/rspec/rspec-rails brindan información acerca de lo que se mezcla con algunos de los diversos tipos de especificaciones.

+1

Tuve el mismo problema, mis especificaciones no funcionaban cuando las puse en las especificaciones/controladores, cuando moví las especificaciones de la API a una carpeta separada, no obtuve este error – shicholas

0

Creo que login(current_user) no funciona con Rack :: Test :: Methods. Necesita una forma de autenticarse a través de su llamada API, tal vez con un token de autenticación.

response está relacionado con ActionController, que conoce su inicio de sesión. Si no me equivoco, las llamadas API son independientes del Controlador, por lo que no sabe que ya ha iniciado sesión.

Consulte Ticketee, la aplicación de ejemplo de Rails 3 in Action, por ejemplo.

Cuestiones relacionadas