I am following a tutorial of building a JSON api using ruby version 2.3.1 and rails version 5.0.7. The tutorial is located at https://scotch.io/tutorials/build-a-restful-json-api-with-rails-5-part-two When running RSpec tests, I get:
Failures:
1) AuthenticationController POST /auth/login when request is valid returns an authentication token Failure/Error: before { post 'auth/login', params: valid_credentials, headers: headers }
NoMethodError:
undefined method `symbolize_keys' for "{\"email\":\"foo@bar.com\",\"password\":\"foobar\"}":String
# ./spec/controllers/authentication_controller_spec.rb:32:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:85:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:84:in `block (2 levels) in <top (required)>'
2) AuthenticationController POST /auth/login When request is invalid returns a failure message Failure/Error: before { post '/auth/login', params: invalid_credentials, headers: headers }
NoMethodError:
undefined method `symbolize_keys' for #<String:0x007fcb133e88f8>
# ./spec/controllers/authentication_controller_spec.rb:41:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:85:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:84:in `block (2 levels) in <top (required)>'
The AuthenticationControllerSpec to which it refers to is as follows:
require 'rails_helper'
RSpec.describe AuthenticationController, type: :controller do
# Authentication test suite
describe 'POST /auth/login' do
# create test user
let!(:user) { create(:user) }
# set headers for authorization
let(:headers) { valid_headers.except('Authorization') }
# set test valid and invalid credentials
let(:valid_credentials) do
{
email: user.email,
password: user.password
}.to_json
end # let(:valid_credentials) do
let(:invalid_credentials) do
{
email: Faker::Internet.email,
password: Faker::Internet.password
}.to_json
end # let(:invalid_credentials) do
# set request.headers to our custom headers
# before { allow(request).to receive(:headers).and_return(headers) }
# returns auth token when request is valid
context 'when request is valid' do
before { post 'auth/login', params: valid_credentials, headers: headers }
it 'returns an authentication token' do
expect(json['auth_token']).not_to be_nil
end # it 'returns an authentication token' do
end # context 'when request is valid' do
# returns failure message when request is invalid
context 'When request is invalid' do
before { post '/auth/login', params: invalid_credentials, headers: headers }
it 'returns a failure message' do
expect(json['message']).to match(/Invalid credentials/)
end # it 'returns a failure message' do
end # context 'When request is invalid' do
end # describe 'POST /auth/login' do
end # RSpec.describe AuthenticationController, type: :controller do
I think the only other relevant file is this module:
module RequestSpecHelper
# Parse JSON response to ruby hash
def json
JSON.parse(response.body)
end
end
Thanks for any and all assistance.
Don't manually convert the params to JSON. RSpec does it automatically for you and expects a hash of parameters and not a string.
let(:valid_credentials) do
{
email: user.email,
password: user.password
}
end
let(:invalid_credentials) do
{
email: Faker::Internet.email,
password: Faker::Internet.password
}
end
Additionally for a new project I would skip controller tests and go straight for request specs which are more future proof .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.