REST Assured를 이용한 API Test에서 POJO를 이용해보는 법에 알아보겠습니다.
https://velog.io/@dion/what-is-POJO
위 벨로그에 잘 나와있어서 링크로 대체합니다 ^^
간단히 말해서 변수들과 생성자, getter, setter로 이루어진 어느 프레임워크에 종속받지 않는 java class라고 생각하시면 편할 것 같습니다.
REST-Assured
에서는 response에 대하여 POJO로의 deserialization(역직렬화), POJO에서 데이터(json, XML)으로의 serialization(직렬화)를 지원합니다.
POJO를 이용하는 장점으로는,
정도가 있습니다.
반대로 단점으로는, 만약 response로 오는 데이터의 구조가 복잡하다면, 그만큼 생성해야하는 POJO class가 많기 때문에 복잡해지며, 클래스를 생성하는데에 시간이 들고, attribute가 자주 변경된다면 그만큼 유지보수하는데에도 코스트가 들게됩니다.
사실, Rest-assured
가 지원하긴하지만, 이 라이브러리도 다른 라이브러리를 사용하고 있어서, 종속적인 관계의 라이브러리를 추가적으로 관리해주어야합니다.
아래와 같이 jackson-databind, jackson-annotation, jackson-core, gson
과 같은, json 데이터를 다루는 라이브러리가 추가적으로 필요합니다.
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
어떻게 해야 POJO를 이용해서 json데이터를 핸들링해볼 수 있을까요?
보통은 API Document에 request로는 어떠한 것들이 필요하고, response는 어떠한 attribute들이 보내지는지 정의되어있습니다. POJO 클래스를 생성하기 전에 우선 document를 보고 이해하는 것이 중요합니다.
만약, 어떠한 request의 response로 아래의 json데이터가 온다고 가정해본다면,
{
url:"http://www.google.com",
services:"google drive",
expertise:"Panda",
course : {
webAutomation:"Selenium",
api:"RestAssured",
mobile:"Appium"
},
instructor:"Panda",
linkedIn:"@dahunyoo
}
위와 똑같은 형태의 클래스들을 작성해주는 것입니다.
public class GetCourse {
private String url;
private String services;
private String exptertise;
private Courses courses;
private String instructor;
private String linkedIn;
.
.
.
//getter and setter
}
public class Courses {
private String webAutomation;
private String api;
private String mobile;
.
.
.
//getter and setter
}
이때, variable의 이름선언으로는, 설사 convention과는 다르더라고 response data와 동일하게 해주어야합니다.
만일, 어떠한 attribute가 array의 형태로 오는 것을 예상한다면, List<T>
로 선언해야할 것 입니다.
예를 들어 위의 course
의 webAutomation, api, mobile
이 여러개가 온다는 것을 가정한다면, 아래와 같이 되어야할 것 입니다.
public class Courses {
private List<WebAutomation> webAutomation;
private List<Api> api;
private List<Mobile> mobile;
.
.
.
//getter and setter
}
이후 각각의 변수들의 클래스들을 별도로 생성해주어야 합니다.
public void actualRequest(String accessToken) {
GetCourse response = given().log().all()
.queryParam("access_token", accessToken).expect().defaultParser(Parser.JSON)
.when().get("{URI}/getCourse.php/")
.as(GetCourse.class);
위 예시에서, 일단 json
format이 오는 것이라고 가정한다면, expect().defaultParser()
에 Parser.JSON
을 지정해주어, 무조건 json형태의 데이터로 파싱할 수 있도록 지정해줍니다.
이후 when()
절에서 데이터를 .as({POJO_CLASS_NAME}.class)
즉, 해당 POJO class로써 받아올 수 있도록 지정해줍니다.
실제로 결과적으로 데이터를 저작하는 변수의 객체형은 Response
가 아닌 GetCourse
형 입니다.
이후 필요에 따라 getter
를 사용해주면서 데이터를 꺼내올 수 있습니다.
System.out.println(response.getLinkedIn());
System.out.println(response.getInstructor());
for (WebAutomation wa: response.getCourses().getWebAutomation()) {
System.out.println( wa.getCourseTitle());
System.out.println(wa.getPrice());
}
반대로 POJO object의 데이터를, request body의 데이터로 보내야하는 경우도 있습니다.
일단 객체를 생성해서 필요한 데이터들을 넣어줍니다.
GetCourse requestBodydata = new GetCourse();
requestBodydata.setUrl("http://www.google.com");
.
.
.
이후 request에 보내면 됩니다.
GetCourse response = given().log().all()
.queryParam("access_token", accessToken).body(requestBodyData)
.expect().defaultParser(Parser.JSON)
.when().get("{URI}/getCourse.php/")
.as(GetCourse.class);