2012-12-18 17 views
9

Ich verwende die rails-api Edelstein, um einen Web-Service aufzubauen und meine API mit RSpec zu testen. Jede Anfrage, die ich mache, hat unabhängig von der HTTP-Methode den Header CONTENT_TYPE als "application/x-www-form-urlencoded" gesetzt. Dies ist nicht wirklich ein Problem, bis ich versuche wrap_parameters in meinem Controller zu verwenden, und es habe keine Auswirkung auf die params hash:Einstellung Content-Type-Header für RSpec und Rails-API

class ApplicationController < ActionController::API 
    include ActionController::ParamsWrapper 
end 

class ProjectsController < ApplicationController 
    wrap_parameters :project, include: [:name] 
    # ... 
end 

This hack nicht mehr funktioniert (@request ist gleich Null), und keiner der anderen Stack Overflow Posts habe ich entweder gefunden.

Wenn ich die folgende Anfrage in meinem RSpec Test machen:

put "/projects/1.json", {name: 'Updated Project 1'} 

und einen Debugger in meinem Controller habe ich bekommen:

(rdb:1) p params 
    { "name"=>"Updated Project 1", 
    "action"=>"update", 
    "controller"=>"projects", 
    "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507", 
    "format"=>"json" 
} 

(rdb:1) p request.content_type 
"application/x-www-form-urlencoded" 

Ich erwarte so etwas wie dies für die sehen params-Hash (man beachte die Zugabe des Leitprojekts):

{ "name"=>"Updated Project 1", 
    "action"=>"update", 
    "controller"=>"projects", 
    "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507", 
    "format"=>"json", 
    "project" => {"name" => "Updated Project 1"} 
} 

Ist es Möglich, den Inhaltstyp Header nur mit RSpec zu setzen? Oder muss ich Rack/Test für diese Funktionalität verwenden?

+0

Es gibt eine Chance, dass [wrap_parameters noch gesprengt] (https://github.com/rails-api/rails-api/issues/33) mit dem Projekt rails-api, und das hat nichts mit dem Festlegen des Inhaltstyps zu tun. –

+0

bestätigt, dass wrap_parameters funktioniert, indem Sie das: url_encoded_form Format Methodenaufruf: 'wrap_parameters Format: [: url_encoded_form,: json]' –

+0

Sie Elemente der rspec Anfrage Umgebung in einem Regler mit 'request.env einstellen [ 'HTTP_CONTENT_TYPE'] = 'application/json'' oder was auch immer du brauchst. – nmott

Antwort

18

Eine Menge Frustration und Variationen und das hat bei mir funktioniert. für mich Rails 3.2.12 Rspec 2,10

@request.env["HTTP_ACCEPT"] = "application/json" 
@request.env["CONTENT_TYPE"] = "application/json" 
put :update, :id => 1, "email" => "[email protected]" 

wrap_parameters scheint diese Weise

erklärt zu funktionieren
wrap_parameters User, format: :json 

für User Modell Rails 4.0.3 Das funktionierte

+1

Das hat mich wirklich gestolpert. Einstellung 'put: update,: id => 1,: format =>: json' wird ** nicht ** funktionieren. Sie müssen wie VelLes eingeben. – maletor

5

verwendet wird und Rspec 2.14.1, wenn jemand nach neueren Versionen sucht.

put '/projects/1.json', {name: 'Updated Project 1'}, { 
    'HTTP_ACCEPT' => 'application/json', 
    'CONTENT_TYPE' => 'application/json' 
} 

und

wrap_parameters Project, format: :json 
+1

Ich entfernte .to_json von params und es funktionierte: 'put '/projects/1.json', {name: 'Aktualisiertes Projekt 1'}, { 'HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' = > 'application/json' } ' –

3

die neuen Rails Mit v5.0.x API nur Einstellungen fand ich, dass dieses Problem mit Schienen alles "application/x-www-form-urlencoded" säumigen noch in der Ausgabe ist für den Test mit RSpec-Rails Anfragen

Hier

ist das, was ich tat, um das Problem zu beheben:

erstellen Support-Datei an ./spec/support/json_requests.rb

bearbeiten es so etwas zu sein, das Verhalten für alle Ihre API nur JSON Anfragen außer Kraft zu setzen:

module JsonRequests 
    def get(*args) 
    super(*json_args(*args)) 
    end 

    def post(*args) 
    super(*json_args(*args)) 
    end 

    def update(*args) 
    super(*json_args(*args)) 
    end 

    def patch(*args) 
    super(*json_args(*args)) 
    end 

    def put(*args) 
    super(*json_args(*args)) 
    end 

    def delete(*args) 
    super(*json_args(*args)) 
    end 

    def json_args(path, params = {}, headers = {}) 
    [path, params.to_json, headers.merge('CONTENT_TYPE' => 'application/json')] 
    end 
end 

RSpec.configure do |config| 
    config.include JsonRequests, type: :request 
end 

Beachten Sie, dass diese alle Specs innerhalb ./spec/requests außer Kraft gesetzt wird also, wenn Sie "application/x-www-form-urlencoded" könnten Sie verwenden müssen auch include dieses Modul manuell wie benötigt in Ihrem Describe 'something' do Block.

0

Wenn Sie Rails 4 (und rspec ~ 3.7) und wollen nicht die Inline-Syntax:

request.headers["CONTENT_TYPE"] = "application/json"