Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 이벤트핸들러this
- string
- JDBC
- model
- TDD
- MVC
- 로그백
- 전전긍긍
- 문제선택근거
- DDD
- springsecurity
- 단위테스트
- 공통기술
- SEQUENCE
- 냄새라도
- Ajax
- Transaction
- 디스크i/o
- 사면초가
- 클린아키텍처
- 공통규약
- SpringLegacy
- AOP
- 이벤트핸들러등록
- index
- JPA
- 설정세팅
- 커뮤니티서버
- MVC요청플로우
- OOP
Archives
- Today
- Total
개발이군고구마
[사면초가 TDD/OOP] 3. 통합테스트 (config mock의 주입) 본문
728x90
❇ 현재 진행단계.
[OOP 설계 프로세스]
1. 설계 원칙 확립 < 구현 1단계
2. TDD 구현 단위 < 구현 2단계
3. TDD 구현 통합
4. 이터레이션과 현실
1. 서비스 통합 테스트
🌐 config mock을 어떻게 만들어 실제 테스트에 주입시킬 것인가
1) 테스트가 실행되는데 세팅되어야할 config 파일 bean으로 spring container에 담아주기
@SpringBootTest(classes = {
GreenApplication.class,
FileTestUtil.class,
MySqlTestContainerConfig.class,
S3TestContainerConfig.class
})
public class ServiceIntegrationTest {
}
a. configuration
설정 환경 빈으로 등록
- MySqlContainer 객체 -> DB 와 연동함
@TestConfiguration
public class MySqlTestContainerConfig {
@Bean
@ServiceConnection
public MySQLContainer<?> mySQLContainer() {
return new MySQLContainer<>("mysql:8.0");
}
}
- S3Client 객체 -> AWS 와 연동함
@TestConfiguration
public class S3TestContainerConfig {
@Bean(initMethod = "start", destroyMethod = "stop")
public LocalStackContainer localStackContainer() {
DockerImageName dockerImageName = DockerImageName.parse("localstack/localstack:3.0");
LocalStackContainer localStackContainer = new LocalStackContainer(dockerImageName);
localStackContainer.withServices(LocalStackContainer.Service.S3);
return localStackContainer;
}
@Bean
public S3Client testS3Client(LocalStackContainer localStackContainer) {
return S3Client.builder()
.endpointOverride(localStackContainer.getEndpointOverride(LocalStackContainer.Service.S3))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create("test", "test")
))
.region(Region.of(localStackContainer.getRegion()))
.build();
}
}
b. component
의존성 주입을 시켜서 메서드들을 이용할 클래스 분리해놓음
▶ 테스트 코드 작성시 긴 메서드를 축약시킬 수 있음
@Component
public class FileTestUtil {
@Autowired
private S3StorageHelper storageHelper;
@Autowired
private S3Properties s3Properties;
@Autowired
private S3Client s3Client;
@Autowired
private FileJpaRepository fileJpaRepository;
public boolean existsImageInS3(String imageUrl) {
String imageKey = storageHelper.extractImageKey(imageUrl);
try {
s3Client.headObject(HeadObjectRequest.builder()
.bucket(s3Properties.getBucket())
.key(imageKey)
.build());
return true;
} catch (NoSuchKeyException e) {
return false;
}
}
....등등
}
2) config를 상속받은 진짜 테스트 클래스
- 성공하는 경우 DB 에 잘 저장되었는지
- 실패하는 경우 예외를 잘 반환하였는지
public class FileServiceIntTest extends ServiceIntegrationTest {
@Autowired
private FileService fileService;
@Autowired
private FileTestUtil fileTestUtil;
@BeforeEach
void setUp() {
fileTestUtil.createBucket();
}
@AfterEach
void tearDown() {
fileTestUtil.clearBucket();
}
// 성공
@Test
void 이미지_파일을_업로드하면_db와_storage에_저장된다() {
// given
MultipartFile imageFile = createMockFile("image1.jpg", "image/jpeg");
// when
String imageUrl = fileService.uploadImage(imageFile, Purpose.PROFILE);
// then
assertThat(fileTestUtil.existsImageInS3(imageUrl)).isTrue();
assertThat(fileTestUtil.existsInImageMetadataInDb(imageUrl)).isTrue();
}
// 실패
@Test
void 이미지_업로드_중_예외가_발생하면_db에_저장된_파일이_롤백된다() {
// given
MultipartFile imageFile = createMockFile("image.png", "image/png");
fileTestUtil.clearBucket();
// when & then
assertThatThrownBy(() -> fileService.uploadImage(imageFile, Purpose.PROFILE))
.isInstanceOf(FileException.class)
.hasFieldOrPropertyWithValue("exceptionMessage", FileExceptionMessage.IMAGE_UPLOAD_FAILED);
assertThat(fileTestUtil.countInImageMetadataInDb()).isZero();
}
private static MultipartFile createMockFile(String originalName, String contentType) {
return new MockMultipartFile("image", originalName, contentType, "imageFile".getBytes());
}
}
- DB 연동 부분 : fileJpaRepository.save(fileEntity);
- AWS 연동 부분 : s3Client.putObject(request, RequestBody.fromInputStream(inputStream, imageFile.getSize()));
'SERVER > Architecture' 카테고리의 다른 글
| [냄새라도 TDD/OOP] 2-1. 단위 테스트 (도메인단) (0) | 2025.06.27 |
|---|---|
| [냄새라도 TDD/OOP] 1. 구현 원칙 확립 (0) | 2025.06.27 |
| [사면초가 TDD/OOP] 2. 단위 테스트 (테스트 하고 있는 메서드만 생각한다) (0) | 2025.05.30 |
| [전전긍긍 설정세팅] 7. DDD와 클린 아키텍처 (#디렉토리 #공통규약) (0) | 2025.05.29 |
| [Architecture] 클린 아키텍처와 OOP (0) | 2025.05.28 |