spec
|--- apis #do not put into controllers folder.
|--- your_api_test_spec.rb
|--- controllers
|--- models
|--- factories
|--- views
|--- helpers
|--- supports
|--- api_helper.rb
|--- authentication_helper.rb
|--- spec_helper.rb
*note: do not put your apis folder underneath controllers folder, otherwise, it will inherited with controller ActionController::TestCase::Behavior
, Rake::Test::Methods
cannot be apply accordingly.
@spec/supports/api_helper.rb
module ApiHelper
include Rack::Test::Methods
def app
Rails.application
end
end
RSpec.configure do |config|
config.include ApiHelper, :type=>:api #apply to all spec for apis folder
end
@spec/spec_helper.rb
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
make sure your sample test group has type: api, then it will include Rake::Test::Methods for (get,post,put,delete
) requests
@spec/apis/authentication_spec.rb
require "spec_helper"
describe "API authentication" , :type => :api do
let!(:user) { FactoryGirl.create(:user) }
it "making a request without cookie token " do
get "/api/v1/items/1",:formate =>:json
last_response.status.should eql(401)
error = {:error=>'You need to sign in or sign up before continuing.'}
last_response.body.should eql(error.to_json)
end
end
Rspec-Rails includes ActionController::TestCase::Behavior
for simulating controller requests.
so you could do
require "spec_helper"
describe Api::V1::SessionsController , :type => :api do
let!(:user) { FactoryGirl.create(:user) }
it "making a request without cookie token " do
get :index
response.status.should eql(401)
error = {:error=>'You need to sign in or sign up before continuing.'}
response.body.should eql(error.to_json)
end
end
Rake::Test::Methods
could query the url "/api/v1/xxxx", butActionController::TestCase::Behavior
only execute actions within current controller scope.- the reponse in
Rake::Test::Methods
called: last_response, inActionController::TestCase::Behavior
called: response.
*Notes, if you change your spec/apis folder to api, you will find out the last_repsonse
is not working any more. That's because the :type=> :api scope got mixed with default ActionController behavior.
@spec/supports/authentication_helper.rb
module AuthenticationHelper
def sign_in_as_a_valid_user
@user ||= FactoryGirl.create(:user)
@user.reset_authentication_token! unless @user.authentication_token
set_cookie "authentication_token=#{@user.authentication_token}"
end
end
RSpec.configure do |config|
config.include AuthenticationHelper, :type=>:api
end
*Notes: The Example above used token based cookie authentication. So you could change to base-authen or token-based auth based on your own needs.
use before_each or before_all block or include the helper method into your assertion block
require "spec_helper"
describe "API Items Controller", :type => :api do
before :each do
sign_in_as_a_valid_user
end
it "fetch all items" do
#or include the helper method here
sign_in_as_a_valid_user
...
end
end
In https://gist.github.com/alex-zige/5795358#enable-spec_helper-supports
It should be
Rails.root.join("spec/supports/**/*.rb")
?