2011-09-03 11 views
15

Jestem trochę zakłopotany. Mam następujący test Integracja:Testowanie odpowiedzi REST-API za pomocą Rspec i 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 

Dodałem wymaganą Rack :: :: Metody testowe, aby mi metodę last_response ale nie wydają się działać dobrze. last_response zawsze wydaje mi pokazać sign_in stronie chociaż ja już zalogowany.

Jeśli usunąć Rack :: testowe :: Formy last_response odchodzi i mogę użyć zamiast response i uzyskać aktualną odpowiedź. Wszystko wydaje się działać dobrze.

Dlaczego tak jest? Skąd się bierze metoda response? Czy mogę użyć response, aby uzyskać poprzednią odpowiedź z sesji?

muszę użyć last_response, lub coś podobnego, dla

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

dzięki czemu można dopasować trasy. Gdyby nie to, byłbym ustawiony.

+1

Co to jest kod dla 'logowania' - czy zdefiniowano metodę rspec, czy zdefiniowałeś ją gdzieś indziej? Czy strona logowania wymaga przekierowania do pracy? Jeśli tak, wpisz "follow_redirect!" Po kodzie logowania. – iain

+0

Jakie jest rozwiązanie, które wymyśliłeś? Pracuję również z przykładem [Ticketee] (https://github.com/rails3book/ticketee), ale nadal 'last_response' nie zawiera odpowiedzi, której oczekuję? Nie zapomnij zaznaczyć jednej z odpowiedzi. – JJD

Odpowiedz

1

response jest automatyczne dla niektórych typów specyfikacji.

Rspec prawdopodobnie miesza ActionController::TestCase::Behavior dla bloków :type => :api.
response będzie pochodzić z ActionController::TestCase::Behavior, podobnie jak w przypadku bloków :type => :controller.

Jeśli chcesz uzyskać odpowiedź przed podaną przez response, spróbuj zapisać ją w zmiennej przed wykonaniem następnej prośby.

https://www.relishapp.com/rspec/rspec-rails/v/2-3/docs/controller-specs i https://github.com/rspec/rspec-rails podać informacje o tym, co miesza się z niektórymi różnymi typami specyfikacji.

+1

Miałem ten sam problem, moje specyfikacje nie działały, gdy umieściłem je w specyfikacji/kontrolerach, kiedy przeniosłem specyfikacje interfejsu API do osobnego folderu nie otrzymałem tego błędu – shicholas

0

Myślę, że login(current_user) nie działa z Rack :: Test :: Methods. Potrzebujesz sposobu uwierzytelnienia za pośrednictwem wywołania API, być może za pomocą tokena uwierzytelniania.

jest związany z ActionController, który zna Twój login. Jeśli się nie mylę, wywołania API są niezależne od kontrolera, więc nie wiadomo, czy jesteś już zalogowany.

Zobacz przykład na przykład Ticketee, przykładowa aplikacja z Rails 3 in Action!