Vor kurzem habe ich API mit Graphql-Ruby implementiert. Natürlich muss ich einen Test für graphql schreiben, aber es scheint verschiedene Methoden zu geben, deshalb werde ich ihn als Memorandum zusammenfassen.
Zuerst werde ich erklären, wie man die API tatsächlich trifft. Das Folgende ist ein Beispiel.
spec.rb
RSpec.describe User, type: :request do
describe 'user' do
it 'Die angegebene usr kann erhalten werden' do
user = create(:user)
post '/graphql', params: { query: query(id: user.id) }
json = JSON.parse(response.body)
data = json['data']['user']
expect(data).to include(
'id' => user.id
)
end
end
end
def query(id:)
<<~GRAPHQL
query {
user(id: "#{id}"){
id
name
}
}
GRAPHQL
end
end
Es ist eine einfache Implementierung, eine Abfrage tatsächlich zu definieren und an eine lokale API zu senden. Dies hat jedoch einige problematische Punkte wie folgt.
Als nächstes ist es eine Methode, um direkt auf Ausführen zu klicken. Dies ist auch aus dem Beispiel
spec.rb
RSpec.describe User, type: :request do
describe 'user' do
it 'Die angegebene usr kann erhalten werden' do
user = create(:user)
#Ändern Sie AppSchema in den definierten Schemanamen
ret = AppSchema.execute(query(id: user.id) context:{current_user: user})
data = ret['data']['user']
expect(data).to include(
'id' => user.id
)
end
end
end
def query(id:)
<<~GRAPHQL
query {
user(id: "#{id}"){
id
name
}
}
GRAPHQL
end
end
Ich erhielt eine Analyse und eine Antwort von json, und die Beschreibung verschwand, was es ein wenig sauberer machte. Es ist auch einfach zu testen, da Sie den Kontext als Argument übergeben können. Andererseits ist das Schreiben einer Abfrage oder das Extrahieren einer ID aus dem JSON-Format mühsam. Das JSON-Format ist ziemlich unpraktisch, insbesondere wenn die Abfrage kompliziert und die Verschachtelung tief ist.
Schauen wir uns ein Beispiel an.
spec.rb
RSpec.describe User, type: :request do
describe 'resolver' do
it 'Was Benutzer bekommen können' do
user = create(:user)
# class_name ist der Klassenname der Auflösung, in die die Logik geschrieben ist
mutation = [class_name].new(field: nil, object: nil, context:{current_user: user})
ret = mutation.resolve(id: user.id)
expect(ret).to eq user
end
end
end
Es war ziemlich ordentlich. Wie Sie sehen können, lese ich die Auflösungsmethode direkt, indem ich die Klasse neu schreibe, in der die Auflösung geschrieben ist. Bei dieser Methode ist der Rückgabewert ein Benutzerobjekt, wodurch der Test sehr einfach zu schreiben ist.
In meinem Fall verwende ich die Methode zum direkten Aufrufen von execute beim Testen der Schnittstelle mit der Front wie ObjectType und die Methode zum direkten Aufrufen von Resolver beim Testen anderer Logik. Ich benutze selten die Methode, die erste API zu treffen.
Bisher habe ich die mir bekannten Testmethoden zusammengefasst. Ich wäre dankbar, wenn jemand sagen könnte, dass es andere gute Möglichkeiten gibt.