¿Cómo probar la publicación del controlador: crear la api JSON en los Rails usando rspec?

Me he estado rasgando el pelo intentando hacer pasar la prueba. Tengo una API JSON que se parece a esto:

{ "data": [ { "id": "b99f8173-0492-457f-9de9-6c1d8d6832ed", "type": "manufacturer_organizations", "attributes": { "account_number": "random test 123" }, "relationships": { "organization": { "data": { "id": "fb20ddc9-a3ee-47c3-bdd2-f710541ff89c", "type": "organizations" } }, "manufacturer": { "data": { "id": "1", "type": "manufacturers" } } } },... 

Estoy intentando hacer un post :create prueba en Rails.

 let!(:manufacturer_organization) {FactoryGirl.create(:manufacturer_organization)} let(:manufacturer_organization2) { FactoryGirl.create(:manufacturer_organization)} ... describe "POST create" do it "posts a valid manufacturer organization data" do authenticate organization = FactoryGirl.create(:organization) manufacturer = FactoryGirl.create(:manufacturer) post :create, manufacturer_organization2.to_json #what should I put here instead? expect(json['data'].length).to eq(2) end #=> error: JSON::ParserError: A JSON text must at least contain two octets! 

He intentado varias publicaciones de SO ( esto) , este y este artículo

Estos son algunos de los bashs que he intentado:

 post :create, params: {organization_id: organization.id, manufacturer: manufacturer.id, account_number: "123 test account number"} #=> error: JSON::ParserError: A JSON text must at least contain two octets! 

o

 post :create, params: :manufacturer_organization_2 #=> NoMethodError: undefined method `symbolize_keys' for :manufacturer_organization_2:Symbol 

o

 json = { :format => 'json', :manufacturer_organization => { :account_number => "foo123", :organization_id => organization.id, :manufacturer_id => manufacturer.id } } post :create, json #=> NoMethodError: undefined method `length' for nil:NilClass 

¿Cómo puedo probar mi controlador para aceptar manufacturer_id, organization_id, and account_number través de la post :create ? Ahora mismo, la forma en que lo json['data'].length es contar la json['data'].length inicial de json['data'].length (inicialmente 1); al final, espero que la json['data'].length sea ​​2 después de la post :create exitosa post :create . ¿Cómo puedo simular la creación de una entrada válida de manufacturer_organization?

Editar:

Lo siento, se me olvidó poner mi ayudante de método json:

 def json JSON.parse(response.body) end 

Además, este pase:

  describe "POST create" do it "posts a valid manufacturer organization data" do authenticate organization = FactoryGirl.create(:organization) manufacturer = FactoryGirl.create(:manufacturer) post :create, {account_number: "Test account numba", organization_id: organization.id, manufacturer_id: manufacturer.id} expect(response).to be_success end 

mientras agrego expect(json['success']).to eq("Yay!") me da este error:

JSON::ParserError: A JSON text must at least contain two octets!

Controlador:

  def create @manufacturer_organization = ManufacturerOrganization.new(manufacturer_organization_params) if @manufacturer_organization.save puts "success!" render json: {success: "Yay!"} else puts "Sorry, something went wrong!" end end def manufacturer_organization_params api_params.permit(:organization_id, :manufacturer_id, :account_number) end 

while @api_params ||= ActionController::Parameters.new(ActiveModelSerializers::Deserialization.jsonapi_parse(params))

En RSpec nunca * necesitas formatear explícitamente los parámetros.

 post :create, params: { foo: 'bar' }, format: :json 

Esto formateará correctamente el hash { foo: 'bar' } como JSON en el cuerpo de la solicitud.

Para crear un hash que coincida con la estructura JSONAPI.org puede crear un ayudante:

 # support/api_spec_helper.rb module APISpecHelper def to_json_api(model) { data: { type: ActiveModel::Naming.plural(model), attributes: model.attributes }.tap do |hash| hash[:id] = model.id if model.persisted? end } end end 

También puede utilizar la gem JSONAPI-RB o ActiveModel :: Serializers para establecer / deconstruir las respuestas / parámetros JSONAPI.


 require 'rails_helper' require 'api_spec_helper' RSpec.request "Manufacturer organizations" do include APISpecHelper describe "POST '/manufacturer_organizations'" do let(:valid_params) do to_json_api(FactoryGirl.build(:manufacturer_organization)) end let(:invalid_params) do to_json_api(ManufacturerOrganization.new( foo: 'bad_value' )) end describe "with valid attributes" do it "creates a manufacturer organization" do expect do post '/manufacturer_organizations', params: valid_params, format: :json end.to change(ManufacturerOrganization, :count).by(+1) end it "has the correct response" do post '/manufacturer_organizations', params: valid_params, format: :json expect(response).to have_status :created expect(response.headers[:location]).to eq( manufacturer_organization_path(ManufacturerOrganization.last) ) end end describe "with valid attributes" do it "does not create a manufacturer organization" do expect do post '/manufacturer_organizations', params: invalid_params, format: :json end.to_not change(ManufacturerOrganization, :count) end it "has the correct response" do post '/manufacturer_organizations', params: invalid_params, format: :json expect(response).to have_status :unproccessable_entity end end end end 

Devolviendo los códigos de estado correctos.

Devolver los códigos de respuesta correctos es bastante simple:

 def create @resource = Resource.create(some_params) if @resource.save # you can respond by pointing at the newly created resource but with no body head :created, location: @resource # or render json: @resource, status: :created, location: @resource else render json: { errors: @resource.errors.full_messages }, status: :unprocessable_entity end end 

Si una solicitud POST no incluyó una ID generada por el cliente y el recurso solicitado se creó con éxito, el servidor DEBE devolver un código de estado 201 creado.
http://jsonapi.org/format/#crud

Otras respuestas
Un servidor PUEDE responder con otros códigos de estado HTTP.
Un servidor PUEDE incluir detalles de error con respuestas de error.

La práctica comúnmente aceptada es usar 422 – Entidad no procesable para errores de validación.

Una pequeña preocupación es que debe usar un serializador para dar la respuesta JSON correcta y también serializar los objetos de error correctos .

    Intereting Posts