使用Rspec和Rack :: Test测试REST-API响应
我有点难过。 我有以下集成测试:
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
我已经添加了所需的Rack :: Test :: Methods来获取last_response
方法,但它似乎无法正常工作。 即使我已经登录, last_response
似乎总是向我显示sign_in页面。
如果我删除Rack :: Test :: Methods last_response
消失了,我可以使用response
而不是我得到当前的响应。 一切似乎都运作正常。
为什么是这样? response
方法来自何处? 我可以使用response
来获取会话的先前响应吗?
我需要使用last_response
或类似的东西
last_response.headers["Location"].should eql(route)
这样我就可以匹配路线了。 如果不是为了这个我会被设定。
某些规格类型的response
是自动的。
Rspec可能会混合ActionController::TestCase::Behavior
for :type => :api
blocks。
response
将来自ActionController::TestCase::Behavior
,就像它:type => :controller
blocks一样。
如果您希望在响应给定之前获得response
,请尝试在发出下一个请求之前将其存储在变量中。
我认为login(current_user)
不适用于Rack :: Test :: Methods。 您需要一种通过API调用进行身份validation的方法,可能使用身份validation令牌。
response
与ActionController绑定,后者知道您的登录信息。 如果我没有弄错,API调用独立于Controller,因此它不知道您已经登录。
有关示例 ,请参阅Rails 3 in Action中的示例应用程序Ticketee !