JSON::ParserError: unexpected token at '' on Rails Rspec - ruby-on-rails
I'm quite having an issue on my Rspec. So basically what I want is to send a request to the API, and have a proper response. When I send the data to the API endpoint, and I puts what it sends, it looks like it sends all the data correctly, but at the response level, it says that I am not sending the required parameters. (I am also using VCR to test)
My RSPEC:
require 'rails_helper'
describe 'Create Vendor', type: :request do
let(:user) { create(:alter_user) }
let(:vendor_attributes) do
{
#These are all the required parameters
vendor: {
token: '',
refcode: '',
request_type: 'renters',
first_name: 'Tony',
last_name: 'Stark',
phone: '6504881234',
phone_type: 'mobile',
email: 'tony#starkindustries.com',
address1: '123 Main Street',
address_city: 'Palo Alto',
address_state: 'CA',
address_zip: '94301',
DOB: '1982-10-27'
}
}
end
after do
VCR.eject_cassette
end
it 'creates a vendor' do
VCR.use_cassette('create_vendor') do
post '/api/v2/vendor', params: vendor_attributes.to_json, headers: {'Content-Type' => 'application/json', Authorization: "Token token=#{user.key}"}
response_body = JSON.parse(response.body)
expect(response_body['refcode']).to eq('corp-api-test')
end
end
it 'fails if the vendor is missing attributes' do
VCR.use_cassette('create_vendor_missing_attributes') do
post '/api/v2/vendor', params: {vendor: {last_name: 'Stark', phone: '6504881234'}}.to_json, headers: {'Content-Type' => 'application/json', Authorization: "Token token=#{user.key}"}
expect(response.status).to eq(422)
end
end
it 'requires Authorization token header' do
post '/api/v2/vendor', params: vendor_attributes.to_json, headers: {'Content-Type' => 'application/json'}
expect(response.status).to eq(401)
end
end
When I execute the rspec filePath I receive this:
Create Vendor
Post Request----: {"request_type":"renters","first_name":"Tony","last_name":"Stark","phone":"6504881234","phone_type":"mobile","email":"tony#starkindustries.com","address1":"123 Main Street","address_city":"Palo Alto","address_state":"CA","address_zip":"94301","DOB":"1982-10-27","token":"6ed469496be882f0163c453627fbcac15b773733db123a7c2faf68f42ea7586a","refcode":"corp-api-test"}
-----------------------------------------------------
Response----: {:action=>"new_vendor", :user_hash=>"e59871c35edb7f622c97acfcc20955e9", :result=>"success", :agent_phone=>"888-888-8888", :vendor_uuid=>"242992518092902061", :policy_shell_uuids=>{"RENT"=>"243548182003445420"}, :marketing_headline=>"Test Marketing Headline", :marketing_content=>"<ul><li>Test Marketing Content</li></ul>"}
-----------------------------------------------------
It was successful
creates a vendor (FAILED - 1)
Post Request----: {"last_name":"Stark","phone":"6504881234","token":"6ed469496be882f0163c453627fbcac15b773733db123a7c2faf68f42ea7586a","refcode":"corp-api-test"}
-----------------------------------------------------
Response----: {:result=>"error", :message=>"missing fields: first_name is a required field, email is a required field, address1 is a required field, address_city is a required field, address_state is a required field, address_zip is a required field, DOB is a required field, phone_type is a required field"}
-----------------------------------------------------
fails if the vendor is missing attributes
requires Authorization token header
Failures:
1) Create Vendor creates a vendor
Failure/Error: response_body = JSON.parse(response.body)
JSON::ParserError:
809: unexpected token at ''
# ./spec/requests/create_vendor_spec.rb:34:in `block (3 levels) in <top (required)>'
# ./spec/requests/create_vendor_spec.rb:32:in `block (2 levels) in <top (required)>'
# ./spec/spec_helper.rb:85:in `block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:84:in `block (2 levels) in <top (required)>'
This is my vendor controller
As you can see here I print what I send to the API, it sends the data but then it fails to create a vendor.
def corp_new_vendor_v2
arguments = create_vendor_arguments
https = Net::HTTP.new(VENDOR_CREATE_VENDOR_URI.host, VENDOR_CREATE_VENDOR_URI.port)
https.use_ssl = true
post_request = Net::HTTP::Post.new(VENDOR_CREATE_VENDOR_URI)
post_request['Content-Type'] = 'application/json'
post_request.body = JSON.dump(arguments)
print "Post Request----: #{post_request.body}\n\n"
print "-----------------------------------------------------\n"
response = JSON.parse(https.request(post_request).read_body).symbolize_keys
print "Response----: #{response}\n\n"
print "-----------------------------------------------------\n"
if response[:result] == 'success'
puts 'It was successful'
else
render json: { error: response[:message] }, status: :unprocessable_entity
end
end
# This is used once we touch the new vendor endpoint, and response with a response
def create_vendor_attributes(response)
response.slice(:action, :user_hash, :result, :vendor_uuid, :policy_shell_uuids, :refcode, :return_URL)
end
def create_vendor_params
params.require(:vendor).permit(
:request_type, :first_name, :last_name, :phone, :phone_type, :email, :address1, :address_city, :address_state, :address_zip, :DOB
)
end
def create_vendor_arguments
create_vendor_params.to_h.merge(token: CORP_RENTER_TOKEN, refcode: CORP_REFCODE)
end
end
What am I missing here? On my spec I'm sending everything but I keep receiving the par JSON error.
I will appreciate the help!
EDIT
binding.pry
Create Vendor
# here it sends all the data as in the unit testing
Post Request (Unit Test)----: {"request_type":"renters","first_name":"Tony","last_name":"Stark","phone":"6504881234","phone_type":"mobile","email":"tony#starkindustries.com","address1":"123 Main Street","address_city":"Palo Alto","address_state":"CA","address_zip":"94301","DOB":"1982-10-27","token":"6ed469496be882f0163c453627fbcac15b773733db123a7c2faf68f42ea7586a","refcode":"corp-api-test"}
-----------------------------------------------------
# And here it responds correctly
Response----(Unit Test): {:action=>"new_vendor", :user_hash=>"e59871c35edb7f622c97acfcc20955e9", :result=>"success", :agent_phone=>"888-888-8888", :vendor_uuid=>"242992518092902061", :policy_shell_uuids=>{"RENT"=>"243548182003445420"}, :marketing_headline=>"Test Marketing Headline", :marketing_content=>"<ul><li>Test Marketing Content</li></ul>"}
-----------------------------------------------------
creates a vendor (FAILED - 1)
# Here for some reason it only sends two parameters
Post Request----(Not Unit Test): {"last_name":"Stark","phone":"6504881234","token":"6ed469496be882f0163c453627fbcac15b773733db123a7c2faf68f42ea7586a","refcode":"corp-api-test"}
-----------------------------------------------------
# And obviously the server response with an error cause it's not sending all the required data.
Response----(Not Unit Test): {:result=>"error", :message=>"missing fields: first_name is a required field, email is a required field, address1 is a required field, address_city is a required field, address_state is a required field, address_zip is a required field, DOB is a required field, phone_type is a required field"}
create method
def create
vendor_new_vendor_v2
end
which uses these two methods to sends the parameters
def create_vendor_params
params.require(:vendor).permit(
:request_type, :first_name, :last_name, :phone, :phone_type, :email, :address1, :address_city, :address_state, :address_zip, :DOB
)
end
def create_vendor_arguments
create_vendor_params.to_h.merge(token: CORP_RENTER_TOKEN, refcode: CORP_REFCODE)
end
specs
it 'creates a vendor' do
VCR.use_cassette('create_vendor') do
post '/api/v2/vendor', params: vendor_attributes.to_json, headers: {'Content-Type' => 'application/json', Authorization: "Token token=#{user.key}"}
response_body = JSON.parse(response.body)
expect(response_body['refcode']).to eq('corp-api-test')
end
end
#I just saw that these two `last_name`and `phone`are being printed on the puts I did above.
it 'fails if the vendor is missing attributes' do
VCR.use_cassette('create_vendor_missing_attributes') do
post '/api/v2/vendor', params: {vendor: {last_name: 'Stark', phone: '6504881234'}}.to_json, headers: {'Content-Type' => 'application/json', Authorization: "Token token=#{user.key}"}
expect(response.status).to eq(422)
end
end
it 'requires Authorization token header' do
post '/api/v2/vendor', params: vendor_attributes.to_json, headers: {'Content-Type' => 'application/json'}
expect(response.status).to eq(401)
end
end
You are missing the render :json for the success.
Update your controller with the following
if response[:result] == 'success'
render json: response, status: :ok
else
render json: { error: response[:message] }, status: :unprocessable_entity
end
Related
Can't get authentication to work with devise-jwt
I am trying to get devise and devise-jwt gems to work so I can implement Authorization into my API only Rails app. I have installed both devise and devise-jwt gems. I followed the instructions on this blog post: https://medium.com/#mazik.wyry/rails-5-api-jwt-setup-in-minutes-using-devise-71670fd4ed03 I implemented the requests specs the author included in his post, and I can't get them to pass. If I put a byebug into the session controller, I see that it's saying the "User needs to sign in or sign up before continuing." Any thoughts on what I'm doing incorrectly? Here are the relevant files: routes.rb Rails.application.routes.draw do namespace :api, path: '', defaults: {format: :json} do namespace :v1 do devise_for :users, path: '', path_names: { sign_in: 'signin', sign_out: 'signout', registration: 'signup' } ... end end controllers/api/v1/sessions_controller.rb class API::V1::SessionsController < Devise::SessionsController respond_to :json private def respond_with(resource, _opts = {}) render json: resource end def respond_to_on_destroy head :no_content end end models/user.rb class User < ApplicationRecord devise :confirmable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :jwt_authenticatable, jwt_revocation_strategy: JwtBlacklist ... end models/jwt_blacklist.rb class JwtBlacklist < ApplicationRecord include Devise::JWT::RevocationStrategies::Blacklist self.table_name = 'jwt_blacklist' end config/initializers/devise.rb Devise.setup do |config| # Setup for devise JWT token authentication config.jwt do |jwt| jwt.secret = Rails.application.secret_key_base jwt.dispatch_requests = [ ['POST', %r{^*/signin$}] ] jwt.revocation_requests = [ ['DELETE', %r{^*/signout$}] ] jwt.expiration_time = 1.day.to_i end config.navigational_formats = [] ... end spec/request/authentication_spec.rb require 'rails_helper' describe 'POST /v1/signin', type: :request do let(:user) { create(:user) } let(:url) { '/v1/signin' } let(:params) do { user: { email: user.email, password: user.password } } end context 'when params are correct' do before do post url, params: params end it 'returns 200' do expect(response).to have_http_status(200) end it 'returns JTW token in authorization header' do expect(response.headers['Authorization']).to be_present end it 'returns valid JWT token' do decoded_token = decoded_jwt_token_from_response(response) expect(decoded_token.first['sub']).to be_present end end context 'when login params are incorrect' do before { post url } it 'returns unathorized status' do expect(response.status).to eq 401 end end end describe 'DELETE /v1/signout', type: :request do let(:url) { '/v1/signout' } it 'returns 204, no content' do delete url expect(response).to have_http_status(204) end end I would expect the tests to pass, but I get the following errors: Test Failures Failures: 1) POST /v1/signin when params are correct returns 200 Failure/Error: expect(response).to have_http_status(200) expected the response to have status code 200 but it was 401 # ./spec/request/authentication_spec.rb:21:in `block (3 levels) in <top (required)>' 2) POST /v1/signin when params are correct returns JTW token in authorization header Failure/Error: expect(response.headers['Authorization']).to be_present expected `nil.present?` to return true, got false # ./spec/request/authentication_spec.rb:25:in `block (3 levels) in <top (required)>' 3) POST /v1/signin when params are correct returns valid JWT token Failure/Error: decoded_token = decoded_jwt_token_from_response(response) NoMethodError: undefined method `decoded_jwt_token_from_response' for #<RSpec::ExampleGroups::POSTV1Signin::WhenParamsAreCorrect:0x00007fec3d3ae158> # ./spec/request/authentication_spec.rb:29:in `block (3 levels) in <top (required)>' Finished in 0.76386 seconds (files took 3.31 seconds to load) 5 examples, 3 failures Failed examples: rspec ./spec/request/authentication_spec.rb:20 # POST /v1/signin when params are correct returns 200 rspec ./spec/request/authentication_spec.rb:24 # POST /v1/signin when params are correct returns JTW token in authorization header rspec ./spec/request/authentication_spec.rb:28 # POST /v1/signin when params are correct returns valid JWT token
I don't know if you found a solution; but I leave an approach I've made; It might helpfull. Taking special attetion to the problem, The solution was to change: decoded_token = decoded_jwt_token_from_response(response) To: decoded_token = JWT.decode(response.headers['authorization'].split(' ').last, Rails.application.credentials.jwt_secret, true) Beacuse I din't find any in the documentation or other place and I chose to decode with method provided by JWT. Also if you see I handle the requests in a different way, but I think that is not a problem at all. require 'rails_helper' require "json" RSpec.describe "POST /login", type: :request do let(:user) { User.create!( username: 'usertest', email: 'usertest#email.com', password: 'passwordtest123', password_confirmation: 'passwordtest123') } let(:url) { '/users/login' } let(:params) do { user: { login: user.email, password: user.password } } end context 'when params are correct' do before do post url, params: params.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' } end it 'returns 200' do expect(response).to have_http_status(200) end it 'returns JTW token in authorization header' do expect(response.headers['authorization']).to be_present end it 'returns valid JWT token' do token_from_request = response.headers['Authorization'].split(' ').last decoded_token = JWT.decode(token_from_request, Rails.application.credentials.jwt_secret, true) expect(decoded_token.first['sub']).to be_present end end context 'when login params are incorrect' do before { post url } it 'returns unathorized status' do expect(response.status).to eq 401 end end end RSpec.describe 'DELETE /logout', type: :request do let(:url) { '/users/logout' } it 'returns 204, no content' do delete url expect(response).to have_http_status(204) end end RSpec.describe 'POST /signup', type: :request do let(:url) { '/users/signup' } let(:params) do { user: { username: 'usertest2', email: 'usertest2#email.com', password: 'passwordtest123', password_confirmation: 'passwordtest123' } } end context 'when user is unauthenticated' do before { post url, params: params.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' } } it 'returns 201' do expect(response.status).to eq 201 end it 'returns a new user' do expect(response).to have_http_status :created end end context 'when user already exists' do before do post url, params: params.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' } post url, params: params.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' } end it 'returns bad request status' do expect(response.status).to eq 400 end it 'returns validation errors' do expect(response_body['errors'].first['title']).to eq('Bad Request') end end end PD: I leave the spec code for register, with a couple differences (requests, url, username params in User model (that's is why I use the login param y the login request), I made all in a sigle spec.rb file, ...) to https://medium.com/#mazik.wyry/rails-5-api-jwt-setup-in-minutes-using-devise-71670fd4ed03. Kepp that in mind.
I believe you need to use the helper sign_in user before making the request for it to be authorized. Check https://github.com/heartcombo/devise, Controller tests
Devise test helper fails to sign in
I have a rails API app using devise_token_auth and in my tests (minitest) I need to send POST requests and signed in users so I used the sign_in method but it doesn't seem to be doing anything. This is my test file require 'test_helper' class ActivityControllerTest < ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers test "post activity" do sign_in users('one') post '/activity/', params: { original_activity_log_file: fixture_file_upload('files/test_gpx.gpx', 'application/gpx'), title: 'test activity', description: 'test description' } assert_response 200 end end And this is the result when run Expected response to be a <200: OK>, but was a <401: Unauthorized> Response body: {"errors":["You need to sign in or sign up before continuing."]}. Expected: 200 Actual: 401 What could be going on here to cause the test to fail?
You're using devise_token_auth in that case plain devise helpers doesn't work, you need perform plain authorization with post request. Here is an example: # make a request in order to get tokens post( api_user_session_path, params: { email: "foo#bar.com", password: "password" }.to_json, headers: { 'Content-Type' => 'application/json', 'Accept' => 'application/json' } ) # fetch data from response client = response.headers['client'] token = response.headers['access-token'] expiry = response.headers['expiry'] token_type = response.headers['token-type'] uid = response.headers['uid'] auth_params = { 'access-token' => token, 'client' => client, 'uid' => uid, 'expiry' => expiry, 'token_type' => token_type } new_client = users('one') get( api_find_client_by_name_path(new_client.name), headers: auth_params ) assert_response :ok
User password update rspec
In my controller, I have a method called update_password, this method updates the user password after validating token. But, my tests are failing.What might be the problem? In my controller, def update_password user = User.find_by(email: params[:email]) if user.nil? render json: { error: 'Could not update' }, status: 422 else user.update(user_params) render json: { message: 'Successfully Updated' }, status: 200 end end def user_params params.permit(:password, :password_confirmation, :current_password, :email) end Test: describe 'update password for valid token' do it'should update the password' do user_params = { password: 'newpassword', password_confirmation: 'newpassword', email: user.email } put '/api/v1/update_password', params: user_params expect(user.password).to eq 'newpassword' expect(user.reload.password_confirmation).to eq 'newpassword' expect(user.reload.password).to eq(user.reload.password_confirmation) json_response = JSON.parse(response.body) expect(json_response['message']).to eq('Successfully Updated') end end Factories: FactoryBot.define do factory :user do sequence(:email) { |n| "user#{n}#example.com" } password 'testcase' username 'testcase' password_confirmation 'testcase' first_name 'testname' last_name 'test' end end Error I have got: 1) UsersRequests update password for valid token should update the password Failure/Error: expect(user.password).to eq 'newpassword' expected: "newpassword" got: "testcase" (compared using ==) # ./spec/requests/users_requests_spec.rb:105:in `block (3 levels) in <top (required)>' Finished in 0.35031 seconds (files took 5.69 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/requests/users_requests_spec.rb:98 # UsersRequests update password for valid token should update the password
Your controller action is fundamentally broken. It returns the wrong response code when a record is not found (422 not 401) and returns 200 no matter if the record is updated or not. You are also letting the user update the email attribute! It should look something like this: def update_password # this will raise ActiveRecord::NotFound if the record cannot be found # this avoids duplication by relying on rescue_from to return 401 - not found user = User.find_by!(email: params[:email]) # You need to check the return value to see if the record was updated! if user.update(update_password_params) # consider omitting the JSON payload as clients can just # use the status code to determine if it was a success render json: { message: 'Successfully Updated' }, status: 200 else render json: { error: 'Could not update' }, status: 422 end end private # this should be a subset of the params and not allow email! def update_password_params params.permit(:password, :password_confirmation, :current_password) end You can also do much better in the spec by using RSpec's change matchers: describe 'update password for valid token' do let!(:user) { create(:user) } let(:user_params) do { password: 'newpassword', password_confirmation: 'newpassword', email: user.email } end # don't start with 'should' it 'updates the password' do expect do put '/api/v1/update_password', params: user_params user.reload end.to change(user, :password).to('newpassword') end it 'is successful' do put '/api/v1/update_password', params: user_params expect(response).to have_http_status 200 end end Your spec should simply test the intendended behavior - that the records password is updated. Testing the password_confirmation is not possible since its a virtual attribute - and not needed here. You instead need to test in a separate spec that the password is not updated if they do not match: describe 'update password with invalid attributes' do let!(:user) { create(:user) } let(:user_params) do { password: 'newpassword', password_confirmation: 'newpasswordxx', email: user.email } end it 'does not update the password' do expect do put '/api/v1/update_password', params: user_params user.reload end.to_not change(user, :password) end it 'reponds with 422' do put '/api/v1/update_password', params: user_params expect(response).to have_http_status 422 end end
RSpec sending raw JSON parameters post request
So I'm trying to test a post request in order to save some book details. The response comes as raw JSON due to its being stringified in the client using formData. So that I can format the response appropriately in the controller. I cannot find any clear way to send raw JSON parameters as rails automatically coerce these parameters as a HASH. Any suggestion? Rails 5.1.4 Rspec 3.7.2 books_spec.rb # Test suite for POST /books describe 'POST /books' do # valid payload let(:valid_attributes) do # send stringify json payload { "title": "Learn Elm", "description": "Some good", "price": 10.20, "released_on": Time.now, "user_id": user.id, "image": "example.jpg" }.to_json end # no implicit conversion of ActiveSupport::HashWithIndifferentAccess into String context 'when the request is valid' do before { post '/books', params: valid_attributes, headers: headers } it 'creates a books' do expect(json['book']['title']).to eq('Learn Elm') end it 'returns status code 201' do expect(response).to have_http_status(201) end end context 'when the request is invalid' do let(:valid_attributes) { { title: nil, description: nil }.to_json } before { post '/books', params: valid_attributes, headers: headers } it 'returns status code 422' do expect(response).to have_http_status(422) end it 'returns a validation failure message' do expect(response.body) .to match(/Validation failed: Title can't be blank, Description can't be blank/) end end end books_controller.rb # POST /books def create #book = current_user.books.create!(book_params) render json: #book, status: :created end def book_params binding.pry # request.params[:book] = HASH parsed = JSON.parse(request.params[:book]) params = ActionController::Parameters.new(parsed) params['image'] = request.params[:image] params.permit( :title, :description, :image, :price, :released_on, :user ) end
#you should try test the request first like this and if you see this helping you I will send you the 200 test describe "#create" do context "when the request format is not json" do let(:error_message) do { "Invalid Request Format" => "Request format should be json" } end before do post :create, headers: { "CONTENT_TYPE": "XML" } end it "should return a status of 400" do expect(response).to have_http_status(400) end it "should return an invalid request format in the body" do expect(json(response.body)).to eql error_message end end end
How can I configure access token in doorkeeper-gem on Rails4?
doorkeeper's spec with token through http header My goal is creating secure API between iOS and Rails4. So I've been trying doorkeeper-gem for a while. But I'm wasting time for testing and configuration now. In detail, the problem is doorkeeper_for method and token transferring through HTTP header. How using http request parameter was successful, but sending token through parameter is not good. So I want to send token with HTTP header, but doorkeeper does not see where request.header["My_TOKEN_PLACE"]. Circumstance Now, I have api_controller.rb, communities_controller.rb, communities_controller_spec.rb, doorkeeper.rb. api_controller.rb class ApiController < ApplicationController before_action :create_token doorkeeper_for :all, scopes: [:app] respond_to :json, handler: :jbuilder private def error_handle raise 'Failed.' end def create_token params[:access_token] = request.headers["HTTP_AUTHENTICATION"] # this does not read by doorkeeper end end and communities_controller.rb class CommunitiesController < ApiController def show #community = Community.find params[:id] end def search Query.create q: #search_form.q if #search_form.q.present? community_search = Community.search title_or_description_cont: #search_form.q #communities = community_search.result(distinct: true).page params[:page] end end and communities_controller_spec.rb require 'spec_helper' describe CommunitiesController do let!(:application) { Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "http://app.com") } let(:user){ create :user } let!(:access_token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "app" } before(:each) do request.env["HTTP_ACCEPT"] = 'application/json' end describe "#show" do let(:community) { create :community } before do request.headers["HTTP_AUTHENTICATION"] = access_token.token get :show, id: community end it { expect(response).to be_success } it { expect(response.status).to be 200 } end describe "#search" do before { get :search, access_token: access_token.token } it { expect(response).to be_success } it { expect(response.status).to be 200 } end end and config/initializer/doorkeeper.rb Doorkeeper.configure do orm :active_record resource_owner_authenticator do User.find id: session[:user_id] default_scopes :app end and result of rspec communities_controller.rb is here. /Users/shogochiai/Documents/anyll% be rspec spec/controllers/communities_controller_spec.rb FF.. Failures: 1) CommunitiesController#show should be success Failure/Error: it { expect(response).to be_success } expected success? to return true, got false # ./spec/controllers/communities_controller_spec.rb:20:in `block (3 levels) in <top(required)>' 2) CommunitiesController#show should equal 200 Failure/Error: it { expect(response.status).to be 200 } expected #<Fixnum:401> => 200 got #<Fixnum:803> => 401 Compared using equal?, which compares object identity, but expected and actual are not the same object. Use `expect(actual).to eq(expected)` if you don't care about object identity in this example. # ./spec/controllers/communities_controller_spec.rb:21:in `block (3 levels) in <top(required)>' Finished in 0.33439 seconds 4 examples, 2 failures Failed examples: rspec ./spec/controllers/communities_controller_spec.rb:20 # CommunitiesController#show should be success rspec ./spec/controllers/communities_controller_spec.rb:21 # CommunitiesController#show should equal 200 Randomized with seed 18521 It seems before do request.headers["HTTP_AUTHENTICATION"] = access_token.token get :show, id: community end is not authenticated and before { get :search, access_token: access_token.token } is authenticated. Supplementary I did pp debug in controller, pp request and pp responce result had have a pair of key-value that "HTTP_AUTHENTICATION": "xrfui24j53iji34.....(some Hash value)".