
테스트는 독립적으로 실행되어야 하지만, 공유 자원을 사용할 경우 문제가 발생할 수 있습니다. 예를 들어, @BeforeAll, @BeforeEach로 테스트 환경을 설정하고 모든 테스트에서 같은 데이터를 사용하면, 한 테스트에서 변경된 데이터가 다른 테스트에 영향을 줄 수 있습니다.
@BeforeEach, @BeforeAll 사용 시 주의점
Data.sql 사용 금지
테스트 실행 후 생성된 데이터를 삭제하여 상태를 초기화합니다.
@AfterEach
void tearDown() {
parkingSlotRepository.deleteAllInBatch();
parkingTicketRepository.deleteAllInBatch();
vehicleRepository.deleteAllInBatch();
}
deleteAllInBatch:
DELETE FROM table 형태로 전체 데이터를 삭제합니다.deleteAll:
SELECT * FROM table; DELETE FROM table WHERE id = ? 형태로 데이터를 조회한 후, 하나씩 삭제합니다.테스트 간에 자원을 공유하면 예상치 못한 결과를 초래할 수 있습니다. 공유 자원이란, 테스트 간에 같은 객체나 데이터를 사용하는 경우를 말합니다. 예를 들어, @BeforeAll, @BeforeEach로 테스트 환경을 설정하고 모든 테스트에서 같은 데이터를 사용하면, 한 테스트에서 변경된 데이터가 다른 테스트에 영향을 줄 수 있습니다.
다음은 @BeforeAll로 주차장의 주차 공간 데이터를 미리 설정하고, 테스트에서 이 데이터를 사용하는 코드입니다. 이 코드는 각 테스트가 동일한 데이터를 공유하며, 테스트 실행 순서에 따라 결과가 달라질 수 있습니다.
static ParkingSlotRepository parkingSlotRepository;
static VehicleRepository vehicleRepository;
@BeforeAll
static void setup() {
// 모든 테스트에서 공유할 데이터 생성
parkingSlotRepository = new ParkingSlotRepository();
vehicleRepository = new VehicleRepository();
ParkingSlot slot1 = new ParkingSlot("A1", true);
ParkingSlot slot2 = new ParkingSlot("A2", true);
parkingSlotRepository.saveAll(List.of(slot1, slot2));
Vehicle vehicle1 = new Vehicle("1234ABCD", "SUV");
Vehicle vehicle2 = new Vehicle("5678EFGH", "Sedan");
vehicleRepository.saveAll(List.of(vehicle1, vehicle2));
}
@BeforeAll로 데이터를 설정: setup() 메서드에서 모든 테스트가 공유하는 데이터를 초기화했습니다. 이는 테스트 간에 동일한 객체(주차 공간과 차량)를 사용하게 만듭니다.테스트의 독립성을 보장하려면, 각 테스트에서 필요한 데이터를 새로 생성해야 합니다.
@DisplayName("차량이 주차되면 주차 공간이 비활성화된다.")
@Test
void parkingReducesAvailableSlots() {
// given
ParkingSlotRepository parkingSlotRepository = new ParkingSlotRepository();
VehicleRepository vehicleRepository = new VehicleRepository();
ParkingSlot slot1 = new ParkingSlot("A1", true);
ParkingSlot slot2 = new ParkingSlot("A2", true);
parkingSlotRepository.saveAll(List.of(slot1, slot2));
Vehicle vehicle = new Vehicle("1234ABCD", "SUV");
vehicleRepository.save(vehicle);
ParkingRequest request = ParkingRequest.builder()
.slotId("A1")
.vehicleId("1234ABCD")
.build();
// when
parkingService.parkVehicle(request);
// then
ParkingSlot slot = parkingSlotRepository.findBySlotId("A1");
assertThat(slot.isAvailable()).isFalse(); // 주차 완료 후 비활성화
}
테스트 간에 자원을 공유하면 예상치 못한 결과를 초래할 수 있습니다.
1. 각 테스트는 독립적으로 실행되며, 새로운 객체와 데이터를 생성해야 합니다.
2. 테스트 실행 순서에 관계없이 동일한 결과를 보장해야 합니다.
3. 클렌징 전략을 사용하면 테스트 환경을 항상 초기 상태로 유지할 수 있습니다.
📌 이 글은 TDD 강의를 학습한 내용을 바탕으로 재구성하였습니다. 문제가 되는 부분이 있다면 수정하겠습니다.