반응형
API 테스트 세팅
package com.example.projectorderservice;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApiTest {
@Autowired
private DatabaseCleanup databaseCleanup;
@LocalServerPort
private int port;
@BeforeEach
void setUp() {
if (RestAssured.port == RestAssured.UNDEFINED_PORT) {
RestAssured.port = port;
databaseCleanup.afterPropertiesSet();
}
databaseCleanup.execute();
}
}
데이터베이스 초기화
package com.example.projectorderservice;
import com.google.common.base.CaseFormat;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Table;
import jakarta.persistence.metamodel.EntityType;
import jakarta.transaction.Transactional;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class DatabaseCleanup implements InitializingBean {
@PersistenceContext
private EntityManager entityManager;
private List<String> tableNames;
@Override
public void afterPropertiesSet() {
final Set<EntityType<?>> entities = entityManager.getMetamodel().getEntities();
tableNames = entities.stream()
.filter(e -> isEntity(e) && hasTableAnnotation(e))
.map(e -> e.getJavaType().getAnnotation(Table.class).name())
.collect(Collectors.toList());
final List<String > entityNames = entities.stream()
.filter(e -> isEntity(e) && !hasTableAnnotation(e))
.map(e -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.getName()))
.collect(Collectors.toList());
tableNames.addAll(entityNames);
}
private boolean hasTableAnnotation(EntityType<?> e) {
return null != e.getJavaType().getAnnotation(Table.class);
}
private boolean isEntity(EntityType<?> e) {
return null != e.getJavaType().getAnnotation(Entity.class);
}
@Transactional
public void execute() {
entityManager.flush();
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate();
for (String tableName : tableNames) {
entityManager.createNativeQuery("TRUNCATE TABLE " + tableName).executeUpdate();
entityManager.createNativeQuery("ALTER TABLE " + tableName + " ALTER COLUMN ID RESTART WITH 1").executeUpdate();
}
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate();
}
}
통합테스트
package com.example.projectorderservice.product;
import com.example.projectorderservice.ApiTest;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
public class ProductApiTest extends ApiTest {
@Test
void 상품등록() {
AddProductRequest request = ProductSteps.상품등록요청_생성();
final var response = ProductSteps.상품등록요청(request);
assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value());
}
@Test
void 상품조회() {
ProductSteps.상품등록요청(ProductSteps.상품등록요청_생성());
Long productId = 1L;
var response = RestAssured.given().log().all()
.when()
.get("/products/{productId}", productId)
.then().log().all()
.extract();
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
assertThat(response.jsonPath().getString("name")).isEqualTo("상품명");
}
}
등록 API 테스트
package com.example.projectorderservice.product;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.springframework.http.MediaType;
public class ProductSteps {
public static ExtractableResponse<Response> 상품등록요청(AddProductRequest requeset) {
return RestAssured.given().log().all()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(requeset)
.when()
.post("/products")
.then()
.log().all().extract();
}
public static AddProductRequest 상품등록요청_생성() {
final String name = "상품명";
final int price = 10000;
final DiscountPolicy discountPolicy = DiscountPolicy.NONE;
AddProductRequest requeset = new AddProductRequest(name, price, discountPolicy);
return requeset;
}
}
gradle 의존성
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.0.0'
implementation 'com.google.guava:guava:33.1.0-jre'
}
반응형