2017-02-09 2 views
0

Ich habe begrenzte Erfahrung mit dem Rest versichert. Wir haben eine Reihe von Tests, bei denen ich normalerweise Beispiele finden kann, oder bei denen Google fehlschlägt, aber ich stehe fest, wenn ich versuche, eine geschachtelte Eigenschaft für ein Element in einem anonymen Array abzugleichen und die Eigenschaften nach oben und unten zu überprüfen (Cousins?) .REST Assured: Wie finde ich Elemente mit verschachtelten Eigenschaften in JSON und validiere andere Eigenschaften

Beispiel JSON:

[ 
    { 
     "id":1, 
     "type":{ 
     "typeId":3, 
     "name":"LPM" 
     }, 
     "status":{ 
     "id":1, 
     "price":1.20, 
     "source":172, 
     "valid":0 
     } 
    }, 
    { 
     "id":2, 
     "type":{ 
     "typeId":2, 
     "name":"ST" 
     }, 
     "status":{ 
     "id":10, 
     "price":1.20, 
     "source":172, 
     "valid":0 
     } 
    } 
] 

Ich bin mit dem Rest zugesichert, und ich möchte das Element in der Liste zu finden, die type.name gleich LPM hat, und dann bestätigen status.price, status.source und status.id von nur, dass Element.

Als ich begann zunächst die Antworten Validierung war es nur möglich, dass ein Element im Array zu sein, so war ich mit:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("[0].type.name", equalToIgnoringCase("LPM")) 
     .body("[0].status.id", equalTo(statusId)) 
     .body("[0].status.source", equalTo(sourceId)) 
     .body("[0].status.price", equalTo(price)); 

Dies ist jedoch nicht mehr gewährleistet, zu arbeiten, wie es sein kann, mehr als ein Element im Array, und die Reihenfolge ist nicht garantiert.

Ich habe meinen Körper überprüft geändert werden:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("type.name", hasItem("LPM")) 
     .body("status.id", hasItem(statusId)) 
     .body("status.source", hasItem(sourceId)) 
     .body("status.price", hasItem(price)); 

Dies ist genug, um den Test zu erhalten passieren, aber dies stellt das Risiko, dass die status.id, status.source und status.price des Elements mit type.name LPM konnte falsch sein, aber dies würde nicht erkannt werden, da sie mit dem Element mit type.name ST verglichen würden.

Deshalb möchte ich in der Lage sein, das Element zu finden, das LPM hat, wie es type.name ist, von denen ich es garantieren kann nur ein, zu sein und dann für status.id, status.source und status.price, überprüfen nur das Element, das heißt NICHT das ST-Element.

Ich habe versucht, meine Körper Matcher zu ändern, um die Elemente mit der type.name, die ich brauche, zu finden, aber ich kann dies nicht zur Arbeit, da ich nicht herausfinden, wie man den Baum, rüber und runter gehen auf andere Attribute im selben Element zu überprüfen:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("$.findAll (it.type.name = LPM}.status.id ", hasItem(statusId)) 
     .body("$.findAll (it.type.name = LPM}.status.source", hasItem(sourceId)) 
     .body("$.findAll (it.type.name = LPM}.status.price", hasItem(price)); 

auch selbst wenn dies funktioniert, würde es den Baum 3 mal suchen, wenn wirklich einmal getan hätte.

Meine mittleren Spiele haben diesen Test bestanden, aber ich möchte das richtig machen. Ich bin mir bewusst, dass ich die Elemente in eine List bekommen und es von dort aus erarbeiten könnte, aber aus Gründen der Konsistenz mit dem Rest unserer Beispiele möchte ich das lieber nicht, obwohl ich derzeit keine andere Option sehe.

Ich habe versucht, Beispiele dafür zu finden, was ich in der Dokumentation zu tun versuche, mehrere Ruhe sicher Tutorials und Beispiele, aber ich habe nicht, so gibt es immer die Möglichkeit, dass dies nicht wirklich möglich ist. Wenn nicht, bin ich glücklich, die Theorie dahinter zu erziehen.

Jede Hilfe wird geschätzt.

+0

Bestehen Sie darauf, dies nur mit REST Assured zu tun? –

+0

@ GrzegorzGórkiewicz Ja, ich möchte kein anderes Test-Framework vorstellen. Wenn ich es nicht so machen kann, wie ich es möchte, dann deserialiere ich den JSON in eine Liste und iteriere darüber. – Clarkey

+0

Ich meinte nicht einen anderen ** Test ** Framework. Ich wollte zum Beispiel mit Google's GSON eine Liste von JSONObjects instanziieren und dann mit Hamcrest bestätigen, dass diese Liste ein Element mit der gesuchten Eigenschaft enthält. –

Antwort

4

Hier ist eine Möglichkeit, es zu tun:

... 
then(). 
     root("find {it.type.name == '%s'}.status"). 
     body("id", withArgs("LPM"), is(1)). 
     body("price", withArgs("LPM"), is(1.20f)). 
     body("source", withArgs("LPM"), is(172)). 
     body("id", withArgs("ST"), is(10)); 

(Sie offensichtlich withArgs auf eine Variable extrahieren als auch zur Vermeidung von Wiederholungen).

find ist Groovys Methode, das erste Element zu finden, das mit dem Prädikat übereinstimmt ({it.type.name == '%s'}), findAll gibt immer eine Liste zurück.

root weist REST an Stellen Sie sicher, dass ein "Root-Pfad" verwendet wird, der in nachfolgenden Erwartungen verwendet wird (siehe docs).

+0

Danke! Das hat perfekt funktioniert. Dies ist eine sehr elegante Lösung; viel besser, als das JSON deserialisieren und iterieren zu müssen. – Clarkey

+0

auch muss ich eindeutig etwas groovy lernen! – Clarkey

Verwandte Themen