@SpringBootTest의 webEnvironment 속성을 사용하여 테스트 서버의 실행 방법을 설정
MOCK의 경우는 @Transactional
을 사용할 수 있다.
그러나 RANDOM_PORT의 경우 싱글스레드가 아니라 클라이언트와 서버가 분리되어 있다.
즉, 멀티 스레드 환경이므로 @Transactional
을 사용할 수 없다.
RESTAssured는 REST API의 테스트 및 검증을 단순화하도록 설계되었다.
HTTP 작업에 대한 검증을 위한 풍부한 API를 활용할 수 있다.
위에서 적었듯이 @webEnvironment에서 RANDOM_PORT를 사용하는 경우(RestAssured를 사용하는 경우) @Transactional
을 사용할 수 없다. 따라서 테스트코드간에 서로 영향을 주지 않기 위해서 조치가 필요하다.
@Service
@ActiveProfiles("test")
public class DatabaseCleanup implements InitializingBean {
@PersistenceContext
private EntityManager entityManager;
private List<String> tableNames;
@Override
public void afterPropertiesSet() {
tableNames = entityManager.getMetamodel().getEntities().stream()
.filter(e -> e.getJavaType().getAnnotation(Entity.class) != null)
.map(e -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.getName()))
.collect(Collectors.toList());
}
@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();
}
Feature 기준으로 인수 테스트 클래스를 나눌 수 있다.
Background 기준으로 setUp 메소드(@beforeEach)를 작성할 수 있다.
Scenario 기준으로 인수 테스트 메소드를 작성할 수 있다.
Feature 내부에 있는 Scenario는 같은 테스트 픽스쳐를 공유한다.
When -> Then -> Given 순서로 작성하는 것을 추천
given, when, then에서 명확한 것은 When이다. 어떤 API를 콜할 것인지는 명확하기 때문이다.
그리고 그다음으로 명확한 것은 then이다. 내가 어떤 값을 기대하고 있는지는 이미 알고 있기 때문이다.
그런 다음에 given을 하는 것이다. 이런 요청을 했을 때 이런 응답이 오려면 어떤 값을 넣어야 할까 이런 순서로 하니 자연스러웠다.