Skip to content

Commit

Permalink
feat(Test): 신규 코드에 대한 테스트 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
limehee committed Jan 4, 2025
1 parent 8ef2272 commit 253e99d
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 45 deletions.
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ object Dependencies {
// Test dependencies
const val springBootStarterTest = "org.springframework.boot:spring-boot-starter-test"
const val springSecurityTest = "org.springframework.security:spring-security-test"
const val mockWebServer = "com.squareup.okhttp3:mockwebserver:${Versions.mockWebServer}"
}
3 changes: 2 additions & 1 deletion buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ object Versions {
const val sonarQube = "6.0.1.5171"
const val checkStyle = "10.20.2"
const val jacoco = "0.8.12"
const val apacheHttpClient = "5.4.1"
const val apacheHttpClient = "5.2.3"
const val mockWebServer = "4.12.0"
}
3 changes: 3 additions & 0 deletions stempo-application/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ dependencies {
implementation(Dependencies.swagger)
implementation(Dependencies.googleAuthenticator)
implementation(Dependencies.apacheHttpClient)

// Test
testImplementation(Dependencies.mockWebServer)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.stempo.config;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.RestClient;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = RestClientConfig.class)
class RestClientConfigTest {

private static MockWebServer mockWebServer;

@Autowired
private ApplicationContext applicationContext;

@Autowired
private RestClient rhythmRestClient;

@BeforeAll
static void setUp() throws IOException {
mockWebServer = new MockWebServer();
mockWebServer.start();
}

@AfterAll
static void tearDown() throws IOException {
mockWebServer.shutdown();
}

// @DynamicPropertySource를 사용하여 rhythm-generator.url을 MockWebServer의 URL로 설정
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
String baseUrl = mockWebServer.url("/api").toString();
registry.add("rhythm-generator.url", () -> baseUrl);
}

@Test
void restClientConfig_빈이_정상적으로_생성된다() {
// given, when
RestClient restClient = applicationContext.getBean(RestClient.class);

// then
assertThat(restClient).isNotNull();
}

@Test
void rhythmRestClient_빈이_올바르게_구성되었는지_확인한다() throws Exception {
// Given
String expectedResponseBody = "{\"message\":\"success\"}";
mockWebServer.enqueue(new MockResponse()
.setResponseCode(200)
.setBody(expectedResponseBody)
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));

// When
ResponseEntity<String> response = rhythmRestClient.get()
.uri("/test-endpoint")
.retrieve()
.toEntity(String.class);

// Then
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo(expectedResponseBody);

// 요청 검증
okhttp3.mockwebserver.RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertThat(recordedRequest.getMethod()).isEqualTo("GET");
assertThat(recordedRequest.getPath()).isEqualTo("/api/test-endpoint");

// 기본 헤더 검증
assertThat(recordedRequest.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -111,16 +113,16 @@ void setUp() {
// given
Pageable pageable = PageRequest.of(0, 10);
UploadedFile uploadedFile = UploadedFile.builder()
.id(1L)
.originalFileName("original.txt")
.saveFileName("file.txt")
.url("http://example.com/files/file.txt")
.build();
.id(1L)
.originalFileName("original.txt")
.saveFileName("file.txt")
.url("http://example.com/files/file.txt")
.build();
UploadedFileResponseDto responseDto = UploadedFileResponseDto.builder()
.originalFileName(uploadedFile.getOriginalFileName())
.url(uploadedFile.getUrl())
.createdAt(uploadedFile.getCreatedAt())
.build();
.originalFileName(uploadedFile.getOriginalFileName())
.url(uploadedFile.getUrl())
.createdAt(uploadedFile.getCreatedAt())
.build();

Page<UploadedFile> uploadedFilesPage = new PageImpl<>(Collections.singletonList(uploadedFile), pageable, 1);

Expand Down Expand Up @@ -188,6 +190,52 @@ void setUp() {
verify(uploadedFileService).saveUploadedFile(any(UploadedFile.class));
}

@Test
void saveRhythmFile_정상적으로_저장하고_URL을_반환한다() throws IOException {
// given
byte[] fileData = "Sample rhythm data".getBytes();
String fileName = "rhythm_120_4_bpm.wav";
String category = "rhythm";
String savedFilePath = "/saved/path/rhythm_120_4_bpm.wav";
String savedFileName = "rhythm_120_4_bpm.wav";
String url = fileUrl + "/" + category + "/" + savedFileName;
String encryptedFilePath = "encryptedPath";

when(fileHandler.saveFile(fileData, category, fileName)).thenReturn(savedFilePath);
when(encryptionUtils.encrypt(savedFilePath)).thenReturn(encryptedFilePath);

// when
String resultUrl = fileService.saveRhythmFile(fileData, fileName);

// then
assertThat(resultUrl).isEqualTo(url);
verify(fileHandler).saveFile(fileData, category, fileName);
verify(encryptionUtils).encrypt(savedFilePath);
verify(uploadedFileService).saveUploadedFile(any(UploadedFile.class));
}

@Test
void saveRhythmFile_저장_중_예외가_발생하면_BaseException을_던진다() throws IOException {
// given
byte[] fileData = "Sample rhythm data".getBytes();
String fileName = "rhythm_120_4_bpm.wav";
String category = "rhythm";

when(fileHandler.saveFile(fileData, category, fileName))
.thenThrow(new IOException("파일 저장 실패"));

// when, then
assertThatThrownBy(() -> fileService.saveRhythmFile(fileData, fileName))
.isInstanceOf(BaseException.class)
.hasMessageContaining("리듬 파일 저장에 실패했습니다: " + fileName)
.extracting("errorCode")
.isEqualTo(ErrorCode.RHYTHM_GENERATION_ERROR);

verify(fileHandler).saveFile(fileData, category, fileName);
verify(encryptionUtils, never()).encrypt(anyString());
verify(uploadedFileService, never()).saveUploadedFile(any(UploadedFile.class));
}

@Test
void deleteFile_파일을_삭제하고_true를_반환한다() {
// given
Expand All @@ -199,9 +247,9 @@ void setUp() {
requestDto.setUrl(url);

UploadedFile uploadedFile = UploadedFile.builder()
.savedPath(encryptedFilePath)
.url(url)
.build();
.savedPath(encryptedFilePath)
.url(url)
.build();

when(uploadedFileService.getUploadedFileByUrl(url)).thenReturn(uploadedFile);
when(encryptionUtils.decrypt(encryptedFilePath)).thenReturn(decryptedFilePath);
Expand Down Expand Up @@ -229,18 +277,18 @@ void setUp() {
requestDto.setUrl(url);

UploadedFile uploadedFile = UploadedFile.builder()
.savedPath(encryptedFilePath)
.url(url)
.build();
.savedPath(encryptedFilePath)
.url(url)
.build();

when(uploadedFileService.getUploadedFileByUrl(url)).thenReturn(uploadedFile);
when(encryptionUtils.decrypt(encryptedFilePath)).thenReturn(decryptedFilePath);
when(fileHandler.deleteFile(decryptedFilePath)).thenReturn(false);

// when, then
assertThatThrownBy(() -> fileService.deleteFile(requestDto))
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.FILE_DELETE_FAILED.getDefaultMessage());
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.FILE_DELETE_FAILED.getDefaultMessage());

verify(uploadedFileService).getUploadedFileByUrl(url);
verify(encryptionUtils).decrypt(encryptedFilePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class FileHandlerTest {
@BeforeEach
void setUp() {
fileHandler = new FileHandler(
new String[]{"exe", "bat"},
tempDir.toString()
new String[]{"exe", "bat"},
tempDir.toString()
);
fileHandler.init();
}
Expand All @@ -37,10 +37,10 @@ void setUp() {
void 파일을_성공적으로_저장한다() throws IOException {
// given
MultipartFile multipartFile = new MockMultipartFile(
"file",
"test.txt",
"text/plain",
"Sample content".getBytes()
"file",
"test.txt",
"text/plain",
"Sample content".getBytes()
);

String category = "docs";
Expand All @@ -49,10 +49,10 @@ void setUp() {
String savedPath = fileHandler.saveFile(multipartFile, category);

// then
assertThat(savedPath).isNotNull();
assertThat(savedPath).contains(tempDir.toString() + File.separator + category);
assertThat(savedPath).isNotNull()
.contains(tempDir.toString() + File.separator + category);
File savedFile = new File(savedPath);
assertThat(savedFile.exists()).isTrue();
assertThat(savedFile).exists();
}

@Test
Expand All @@ -67,54 +67,75 @@ void setUp() {
// then
assertThat(savedPath).isNotNull();
File savedFile = new File(savedPath);
assertThat(savedFile.exists()).isTrue();
assertThat(savedFile).exists();
assertThat(Files.readString(savedFile.toPath())).isEqualTo("Sample content");
}

@Test
void 파일명에_잘못된_문자열이_포함되어_있을_경우_예외가_발생한다() {
// given
MultipartFile multipartFile = new MockMultipartFile(
"file",
"test..txt",
"text/plain",
"Sample content".getBytes()
"file",
"test..txt",
"text/plain",
"Sample content".getBytes()
);

String category = "docs";

// then
assertThatThrownBy(() -> fileHandler.saveFile(multipartFile, category))
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.INVALID_FILE_NAME.getDefaultMessage());
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.INVALID_FILE_NAME.getDefaultMessage());
}

@Test
void 잘못된_확장자를_가진_파일을_저장하려_할_때_예외가_발생한다() {
// given
MultipartFile multipartFile = new MockMultipartFile(
"file",
"test.exe",
"application/octet-stream",
"Sample content".getBytes()
"file",
"test.exe",
"application/octet-stream",
"Sample content".getBytes()
);

String category = "docs";

// then
assertThatThrownBy(() -> fileHandler.saveFile(multipartFile, category))
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.INVALID_FILE_ATTRIBUTE.getDefaultMessage());
.isInstanceOf(BaseException.class)
.hasMessageContaining(ErrorCode.INVALID_FILE_ATTRIBUTE.getDefaultMessage());
}

@Test
void 파일_데이터로_성공적으로_파일을_저장하고_URL을_반환한다() throws IOException {
// given
byte[] fileData = "Sample byte content".getBytes();
String category = "images";
String fileName = "picture.png";
String expectedExtension = "png";

// when
String savedPath = fileHandler.saveFile(fileData, category, fileName);

// then
assertThat(savedPath).isNotNull()
.contains(tempDir.toString() + File.separator + category)
.endsWith("." + expectedExtension);

File savedFile = new File(savedPath);
assertThat(savedFile).exists();
assertThat(Files.readAllBytes(savedFile.toPath())).isEqualTo(fileData);
}

@Test
void 파일을_성공적으로_삭제한다() throws IOException {
// given
MultipartFile multipartFile = new MockMultipartFile(
"file",
"test.txt",
"text/plain",
"Sample content".getBytes()
"file",
"test.txt",
"text/plain",
"Sample content".getBytes()
);

String category = "docs";
Expand All @@ -126,7 +147,7 @@ void setUp() {
// then
assertThat(isDeleted).isTrue();
File savedFile = new File(savedPath);
assertThat(savedFile.exists()).isFalse();
assertThat(savedFile).doesNotExist();
}

@Test
Expand Down

0 comments on commit 253e99d

Please sign in to comment.