Ruby Language
Reine RSpec-JSON-API-Prüfung
Suche…
Serializer-Objekt testen und in Controller einführen
Angenommen , Sie möchten Ihre API so entwickeln, dass sie der Spezifikation von jsonapi.org entspricht, und das Ergebnis sollte folgendermaßen aussehen:
{
"article": {
"id": "305",
"type": "articles",
"attributes": {
"title": "Asking Alexandria"
}
}
}
Test für Serializer-Objekt kann folgendermaßen aussehen:
# spec/serializers/article_serializer_spec.rb
require 'rails_helper'
RSpec.describe ArticleSerializer do
subject { described_class.new(article) }
let(:article) { instance_double(Article, id: 678, title: "Bring Me The Horizon") }
describe "#as_json" do
let(:result) { subject.as_json }
it 'root should be article Hash' do
expect(result).to match({
article: be_kind_of(Hash)
})
end
context 'article hash' do
let(:article_hash) { result.fetch(:article) }
it 'should contain type and id' do
expect(article_hash).to match({
id: article.id.to_s,
type: 'articles',
attributes: be_kind_of(Hash)
})
end
context 'attributes' do
let(:article_hash_attributes) { article_hash.fetch(:attributes) }
it do
expect(article_hash_attributes).to match({
title: /[Hh]orizon/,
})
end
end
end
end
end
Das Serializer-Objekt kann folgendermaßen aussehen:
# app/serializers/article_serializer.rb
class ArticleSerializer
attr_reader :article
def initialize(article)
@article = article
end
def as_json
{
article: {
id: article.id.to_s,
type: 'articles',
attributes: {
title: article.title
}
}
}
end
end
Wenn wir unsere "Serialisierer" ausführen, ist alles bestanden.
Das ist ziemlich langweilig. Führen wir einen Tippfehler in unseren Artikel-Serialisierer ein: Anstelle von type: "articles" wir type: "events" und führen unsere Tests erneut aus.
rspec spec/serializers/article_serializer_spec.rb
.F.
Failures:
1) ArticleSerializer#as_json article hash should contain type and id
Failure/Error:
expect(article_hash).to match({
id: article.id.to_s,
type: 'articles',
attributes: be_kind_of(Hash)
})
expected {:id=>"678", :type=>"event",
:attributes=>{:title=>"Bring Me The Horizon"}} to match {:id=>"678",
:type=>"articles", :attributes=>(be a kind of Hash)}
Diff:
@@ -1,4 +1,4 @@
-:attributes => (be a kind of Hash),
+:attributes => {:title=>"Bring Me The Horizon"},
:id => "678",
-:type => "articles",
+:type => "events",
# ./spec/serializers/article_serializer_spec.rb:20:in `block (4
levels) in <top (required)>'
Wenn Sie den Test ausgeführt haben, können Sie den Fehler leicht erkennen.
Sobald Sie den Fehler behoben haben (korrigieren Sie den Typ als article ), können Sie ihn wie folgt in Controller einführen:
# app/controllers/v2/articles_controller.rb
module V2
class ArticlesController < ApplicationController
def show
render json: serializer.as_json
end
private
def article
@article ||= Article.find(params[:id])
end
def serializer
@serializer ||= ArticleSerializer.new(article)
end
end
end
Dieses Beispiel basiert auf dem Artikel: http://www.eq8.eu/blogs/30-pure-rspec-json-api-testing