How to use java objects in Rest Assured effectively
Using objects is more convenient for complex assertion logics and dynamic requests. But java's boiler plate code makes it very difficult to maintain such request and response pojo's when it comes to rest api automation.
Hence we can make use of Lombok and Jackson's annotation for this purpose. It helps in reducing huge lines of code and automating complex orchestration in an easy manner.
Let's look at an example :
Say we have a "Payment" endpoint, which accepts 'SavedCard' and 'NewCard' as payment methods i.e a polymorphic request, for the same endpoint. In such cases we would write different sub classes for each modification in request or response. This makes java for restapi automation cumbersome and tedious.
But let's see how easily we can achieve the same using Jackson & Lombok annotations in Java.
Sample Request :
New Card :
{
"cartId": "a123",
"paymentMethod": {
"newCardPayment": {
"cardAlias": "My Visa",
"cardId": "oeff1234kasd",
"cvv": "123",
}
}
}
Saved Card :
{
"cartId": "a123",
"paymentMethod": {
"savedCardPayment": {
"cardAlias": "mycard"
}
}
}
Sample Response :
{
"transactionId": "TWRE123524",
"transactionRef": "PQRKMETLO",
"emailId": "abc@test.com",
}
POJO Classes
package requestBuilder;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
//All POJO's required for Payment endpoint are written in this class
public class PaymentBuilders {
@Data
@Builder
@AllArgsConstructor
public static class savedCardPayment {
private String cardAlias;
}
@Data
@Builder
@AllArgsConstructor
public static class newCardPayment {
private String cardId;}
private String cardAlias;
private String cvv;
@Data
@Builder
@AllArgsConstructor
public static class paymentRequest {
private String cartId;
@JsonTypeInfo(include = As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME, visible = false)
@JsonSubTypes({ @JsonSubTypes.Type(value = savedCardPayment.class, name = "savedCardPayment"),
@JsonSubTypes.Type(value = newCardPayment.class, name = "newCardPayment") })
private Object paymentMethod;
}
@Data
@Builder
@NoArgsConstructor
public static class paymentResponse {
@NonNull
@JsonProperty("transactionId")
private String transId;
@NonNull
@JsonProperty("transactionReference")
private String transRef;
@NonNull
private String emailId;
}
}
Simple explanation :
1. @NonNull annotation for each variable in paymentResponse class, means the value cannot
be null. Hence, adding assertions separately for the fields is not necessary.
2. @JsonProperty annotation is used when the variable in POJO is of different name than key in
json. This comes very handy when name is java reserved keywords like class, new etc
3. @NoArgsConstructor generates a no argument constructor
4. @AllArgsConstructor generates an all argument constructor
5. @Data generates 'getters' for all fields, 'setters' for all non-final fields, and
appropriate 'toString', 'equals', and 'hashCode' implementations that involve the fields of the
class. This is the most useful annotation of Lombok, which reduces major boilerplate java code.
TEST
orderRequest savedCard = orderRequest.builder().cartId("a123").paymentMethod((new savedCardPayment("mycard"))).build();
orderRequest newCard = orderRequest.builder().cartId("a123").paymentMethod((new newCardPayment("My Visa","oeff1234kasd","123"))).build();RequestSpecification request = RestAssured.given();
request.body(savedCard);
OR
request.body(newCard);
Response response = request.post(RestAssured.baseURI + "/payment");
//Now similarly validate response by parsing it as Java object. Due to the @NotNull annotation, response is already asserted.
paymentResponse payObj = response.jsonPath().getObject(".", paymentResponse.class);
TADA ! That's it ! We achieved a complete flow with just few lines of code.
Comments
Post a Comment