2016-03-28 22 views
2

Ich baue eine API, wo Users folgen kann und von anderen Users gefolgt werden. Ich habe eine Relationship Tabelle erstellt, um die Assoziationen zusammen mit Relationship Endpunkten zu behandeln. Hier ist mein Endpunkt für folgende Person:Rails API rspec Tests

def create 
user = User.find(params[:followed_id]) 
if user 
    current_user.follow(user) 
    render json: [current_user, Relationship.where(followed_id: user.id, follower_id: current_user.id)], status: 201, location: [:api, current_user] 
else 
    render json: { errors: current_user.errors }, status: 422 
end 
end 

Alles funktioniert wie vorgesehen. Wie Sie sehen können, möchte ich mit meinem current_user Objekt und dem neu erstellten Objekt Relationship antworten. Beides funktioniert, wenn ich diesen Endpunkt erreiche, indem ich ein Berechtigungs-Token und die ID des Benutzers, dem ich folgen möchte, bereitstelle. Das Problem, das ich habe, testet, dass ich ein Relationship Objekt zurückbekomme. Hier sind die Tests, die ich für den folgenden Endpunkt haben:

describe "POST #create" do 

context "When relationship is successfully created" do 
    before(:each) do 
    @user = FactoryGirl.create(:user) 
    other_user = FactoryGirl.create(:user) 
    api_authorization_header(@user.auth_token) 
    post :create, followed_id: other_user.id 
    end 

    it "should respond w/ current_user object" do 
    user_response = JSON.parse(response.body, symbolize_names: true) 
    expect(user_response[0][:id]).to eq(@user.id) 
    end 

### THIS TEST IS FAILING & THE ONE THAT I NEED HELP WITH. 
    it "should respond w/ created relationship object" do 
    user_response = JSON.parse(response.body, symbolize_names: true) 
    expect(user_response[1]).to be_kind_of(Relationship) 
    end 

    it { should respond_with(201) } 
end 

end 

Hier sind einige Ausgänge von user_response:

user_response = {:id=>1233, :email=>"[email protected]", :first_name=>"Marcelina", :last_name=>"Morissette", :created_at=>"2016-03-28T18:16:09.875Z", :updated_at=>"2016-03-28T18:16:09.875Z", :auth_token=>"Ky25sYoJc4gH-p122yEH"} 
{:id=>150, :follower_id=>1233, :followed_id=>1234, :created_at=>"2016-03-28T18:16:09.892Z", :updated_at=>"2016-03-28T18:16:09.892Z"} 

Sie sehen user_response ist ein Array der beiden Objekte zurückkehr ich gebeten, zu antworten .

user_response[1] = {:id=>150, :follower_id=>1233, :followed_id=>1234, :created_at=>"2016-03-28T18:16:09.892Z", :updated_at=>"2016-03-28T18:16:09.892Z"} 

Hier gibt es Fehler, die ich erhalten, wenn zu laufen `erwarten (USER_RESPONSE [1]) versuchen. (Beziehung)

1) Api::V1::RelationshipController POST #create When relationship is successfully created should respond w/ created relationship object 
Failure/Error: expect(user_response[1]).to be_kind_of(Relationship) 
    expected [{:id=>153, :follower_id=>1239, :followed_id=>1240, :created_at=>"2016-03-28T18:18:43.064Z", :updated_at=>"2016-03-28T18:18:43.064Z"}] to be a kind of Relationship(id: integer, follower_id: integer, followed_id: integer, created_at: datetime, updated_at: datetime) 
# ./spec/controllers/api/v1/relationship_controller_spec.rb:27:in `block (4 levels) in <top (required)>' 

Vorschläge, wie ich testen kann be_kind_of dass das zweite Objekt zu sein Zurückgesendet ist ein Objekt aus der Beziehungsklasse? Wenn es einen "richtigen" Weg für die Handhabung dieses Endpunkts gibt, würde ich mich über die Lektion freuen =).

Antwort

1

Die Methode "create" gibt eine JSON-Antwort und kein ActiveRecord-Objekt zurück. Eine HTTP-Antwort kann nicht "be_kind_of (Beziehung)" sein. JSON ist nur formatierter Text.

Wenn Sie eine RESTful-API erstellen, müssen Sie die JSON-Antworten und den HTTP-Status in den Anforderungen testen und die Controller nicht testen. Etwas wie:

it 'updates a user on update_user action' do 
    params = { 
    id:  @user.id, # FactoryGirl object 
    fname: 'John', 
    lname: 'Smith', 
    email: '[email protected]' 
    } 

    post '/v1/users/update', params, @env 

    # test for the 200 status-code 
    expect(response).to be_success 
    expect(json['data']['email']).to eq '[email protected]' 
end 

BTW, sollten Sie nicht Sitzungen in Ihrer API verwenden. Stattdessen senden Sie Ihre Benutzer-ID als Parameter in Ihrer Anfrage.

http://matthewlehner.net/rails-api-testing-guidelines/

+0

Okay, das macht Sinn. Ich habe es nur geändert, um die "Follower_id" gegen die "@ user" ID zu überprüfen. – Nappstir

+0

In Bezug auf die Verwendung von Sitzungen in Ihrer API. Der von Ihnen freigegebene Link verwendet auch Sitzungen in der API-Demonstration. Was ich auch tue, um ein 'auth_token' bei erfolgreichen Logins zurückzugeben. Andere Beispiele/Tutorials, auf die ich verwiesen habe, behandeln Benutzeranmeldungen über eine 'zustandslose' Sitzung, die ein Authentifizierungstoken zurückgibt. Gibt es einen besseren Weg, damit umzugehen? – Nappstir

+0

Ich möchte alle Daten, die die Funktion benötigt, als JSON-Objekt senden, da dieser Weg expliziter und einfacher in der Dokumentation zu setzen ist: https://api.yourcompany.com/v1/crateuser/{token_number:'3453xf343 ', token_secret:' ***** ', user_id: 56, follower_id: 36} Beachten Sie das "https" -Protokoll. Der Benutzer sendet die Toek und den Token_Secret in allen Anrufen. – aarkerio