JSON::ParserError: unexpected token at '' on Rails Rspec

JSON::ParserError: unexpected token at '' on Rails Rspec

我的 Rspec 有点问题。所以基本上我想要的是向 API 发送请求并得到适当的响应。当我将数据发送到 API 端点时,我 puts 它发送的内容,看起来它正确发送了所有数据,但在响应级别,它说我没有发送所需的参数。 (我也是用VCR测试的)

我的RSPEC:

需要'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

当我执行 rspec 文件路径时,我收到:

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)>'

这是我的供应商控制器

正如您在这里看到的,我打印了我发送到 API 的内容,它发送了数据,但随后无法创建供应商。

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

我在这里错过了什么?根据我的规范,我发送了所有内容,但我一直收到 par JSON 错误。

非常感谢您的帮助!

编辑

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"}

创建方法

def create
    vendor_new_vendor_v2
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

规格

  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

您错过了成功的 render :json

使用以下内容更新您的控制器

if response[:result] == 'success'
      render json: response, status: :ok
    else
      render json: { error: response[:message] }, status: :unprocessable_entity
    end