Skip to content

Commit 730f235

Browse files
Maintenance: ApiResponse - Add comprehensive test coverage
Added comprehensive unit tests for the ApiResponse class to ensure correctness and prevent regressions. The ApiResponse class is a critical infrastructure component used throughout the application for standardizing API responses. Test coverage includes: - Success response creation (with and without data) - Error response creation (with and without additional data) - Semantic validation (success/error field invariants) - Integration with ErrorMessage class - Edge cases (null data, complex objects) All tests follow the project's testing conventions using @UnitTest annotation and AssertJ for assertions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent 312323d commit 730f235

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
package spring.memewikibe.support.response;
2+
3+
import org.junit.jupiter.api.DisplayName;
4+
import org.junit.jupiter.api.Nested;
5+
import org.junit.jupiter.api.Test;
6+
import spring.memewikibe.annotation.UnitTest;
7+
import spring.memewikibe.support.error.ErrorMessage;
8+
import spring.memewikibe.support.error.ErrorType;
9+
10+
import static org.assertj.core.api.BDDAssertions.then;
11+
12+
@UnitTest
13+
class ApiResponseTest {
14+
15+
@Nested
16+
@DisplayName("success() 메서드는")
17+
class SuccessMethod {
18+
19+
@Test
20+
@DisplayName("데이터 없이 성공 응답을 생성한다")
21+
void createSuccessResponseWithoutData() {
22+
// when
23+
ApiResponse<?> response = ApiResponse.success();
24+
25+
// then
26+
then(response.getResultType()).isEqualTo(ResultType.SUCCESS);
27+
then(response.getSuccess()).isNull();
28+
then(response.getError()).isNull();
29+
}
30+
31+
@Test
32+
@DisplayName("데이터와 함께 성공 응답을 생성한다")
33+
void createSuccessResponseWithData() {
34+
// given
35+
String data = "test data";
36+
37+
// when
38+
ApiResponse<String> response = ApiResponse.success(data);
39+
40+
// then
41+
then(response.getResultType()).isEqualTo(ResultType.SUCCESS);
42+
then(response.getSuccess()).isEqualTo(data);
43+
then(response.getError()).isNull();
44+
}
45+
46+
@Test
47+
@DisplayName("null 데이터로 성공 응답을 생성한다")
48+
void createSuccessResponseWithNullData() {
49+
// when
50+
ApiResponse<String> response = ApiResponse.success(null);
51+
52+
// then
53+
then(response.getResultType()).isEqualTo(ResultType.SUCCESS);
54+
then(response.getSuccess()).isNull();
55+
then(response.getError()).isNull();
56+
}
57+
58+
@Test
59+
@DisplayName("복잡한 객체로 성공 응답을 생성한다")
60+
void createSuccessResponseWithComplexObject() {
61+
// given
62+
TestData testData = new TestData("name", 123);
63+
64+
// when
65+
ApiResponse<TestData> response = ApiResponse.success(testData);
66+
67+
// then
68+
then(response.getResultType()).isEqualTo(ResultType.SUCCESS);
69+
then(response.getSuccess()).isEqualTo(testData);
70+
then(response.getError()).isNull();
71+
}
72+
}
73+
74+
@Nested
75+
@DisplayName("error() 메서드는")
76+
class ErrorMethod {
77+
78+
@Test
79+
@DisplayName("ErrorType만으로 에러 응답을 생성한다")
80+
void createErrorResponseWithErrorType() {
81+
// given
82+
ErrorType errorType = ErrorType.MEME_NOT_FOUND;
83+
84+
// when
85+
ApiResponse<?> response = ApiResponse.error(errorType);
86+
87+
// then
88+
then(response.getResultType()).isEqualTo(ResultType.ERROR);
89+
then(response.getSuccess()).isNull();
90+
then(response.getError()).isNotNull();
91+
then(response.getError().code()).isEqualTo(errorType.getCode().name());
92+
then(response.getError().message()).isEqualTo(errorType.getMessage());
93+
then(response.getError().data()).isNull();
94+
}
95+
96+
@Test
97+
@DisplayName("ErrorType과 추가 데이터로 에러 응답을 생성한다")
98+
void createErrorResponseWithErrorTypeAndData() {
99+
// given
100+
ErrorType errorType = ErrorType.EXTERNAL_SERVICE_BAD_REQUEST;
101+
String errorData = "Invalid request format";
102+
103+
// when
104+
ApiResponse<?> response = ApiResponse.error(errorType, errorData);
105+
106+
// then
107+
then(response.getResultType()).isEqualTo(ResultType.ERROR);
108+
then(response.getSuccess()).isNull();
109+
then(response.getError()).isNotNull();
110+
then(response.getError().code()).isEqualTo(errorType.getCode().name());
111+
then(response.getError().message()).isEqualTo(errorType.getMessage());
112+
then(response.getError().data()).isEqualTo(errorData);
113+
}
114+
115+
@Test
116+
@DisplayName("다양한 ErrorType으로 에러 응답을 생성한다")
117+
void createErrorResponseWithDifferentErrorTypes() {
118+
// when & then
119+
ApiResponse<?> notFoundResponse = ApiResponse.error(ErrorType.MEME_NOT_FOUND);
120+
then(notFoundResponse.getError().code()).isEqualTo("E404");
121+
122+
ApiResponse<?> internalErrorResponse = ApiResponse.error(ErrorType.DEFAULT_ERROR);
123+
then(internalErrorResponse.getError().code()).isEqualTo("E500");
124+
125+
ApiResponse<?> serviceErrorResponse = ApiResponse.error(ErrorType.EXTERNAL_SERVICE_ERROR);
126+
then(serviceErrorResponse.getError().code()).isEqualTo("E503");
127+
}
128+
129+
@Test
130+
@DisplayName("복잡한 객체를 에러 데이터로 사용할 수 있다")
131+
void createErrorResponseWithComplexErrorData() {
132+
// given
133+
ErrorType errorType = ErrorType.EXTERNAL_SERVICE_BAD_REQUEST;
134+
TestData errorData = new TestData("field", 42);
135+
136+
// when
137+
ApiResponse<?> response = ApiResponse.error(errorType, errorData);
138+
139+
// then
140+
then(response.getResultType()).isEqualTo(ResultType.ERROR);
141+
then(response.getError()).isNotNull();
142+
then(response.getError().data()).isEqualTo(errorData);
143+
}
144+
145+
@Test
146+
@DisplayName("null을 에러 데이터로 사용할 수 있다")
147+
void createErrorResponseWithNullErrorData() {
148+
// given
149+
ErrorType errorType = ErrorType.DEFAULT_ERROR;
150+
151+
// when
152+
ApiResponse<?> response = ApiResponse.error(errorType, null);
153+
154+
// then
155+
then(response.getResultType()).isEqualTo(ResultType.ERROR);
156+
then(response.getError()).isNotNull();
157+
then(response.getError().data()).isNull();
158+
}
159+
}
160+
161+
@Nested
162+
@DisplayName("ApiResponse는")
163+
class ApiResponseSemantics {
164+
165+
@Test
166+
@DisplayName("성공 응답은 에러 필드가 null이다")
167+
void successResponseHasNullError() {
168+
// when
169+
ApiResponse<?> emptySuccess = ApiResponse.success();
170+
ApiResponse<String> dataSuccess = ApiResponse.success("data");
171+
172+
// then
173+
then(emptySuccess.getError()).isNull();
174+
then(dataSuccess.getError()).isNull();
175+
}
176+
177+
@Test
178+
@DisplayName("에러 응답은 성공 필드가 null이다")
179+
void errorResponseHasNullSuccess() {
180+
// when
181+
ApiResponse<?> errorResponse1 = ApiResponse.error(ErrorType.MEME_NOT_FOUND);
182+
ApiResponse<?> errorResponse2 = ApiResponse.error(ErrorType.DEFAULT_ERROR, "data");
183+
184+
// then
185+
then(errorResponse1.getSuccess()).isNull();
186+
then(errorResponse2.getSuccess()).isNull();
187+
}
188+
189+
@Test
190+
@DisplayName("성공 응답의 resultType은 SUCCESS다")
191+
void successResponseHasSuccessResultType() {
192+
// when
193+
ApiResponse<?> response = ApiResponse.success("data");
194+
195+
// then
196+
then(response.getResultType()).isEqualTo(ResultType.SUCCESS);
197+
}
198+
199+
@Test
200+
@DisplayName("에러 응답의 resultType은 ERROR다")
201+
void errorResponseHasErrorResultType() {
202+
// when
203+
ApiResponse<?> response = ApiResponse.error(ErrorType.MEME_NOT_FOUND);
204+
205+
// then
206+
then(response.getResultType()).isEqualTo(ResultType.ERROR);
207+
}
208+
}
209+
210+
@Nested
211+
@DisplayName("ErrorMessage 통합 테스트")
212+
class ErrorMessageIntegration {
213+
214+
@Test
215+
@DisplayName("ApiResponse의 에러는 올바른 ErrorMessage 구조를 가진다")
216+
void errorResponseHasCorrectErrorMessageStructure() {
217+
// given
218+
ErrorType errorType = ErrorType.CATEGORY_NOT_FOUND;
219+
String additionalData = "category-id-123";
220+
221+
// when
222+
ApiResponse<?> response = ApiResponse.error(errorType, additionalData);
223+
224+
// then
225+
ErrorMessage error = response.getError();
226+
then(error).isNotNull();
227+
then(error.code()).isEqualTo(errorType.getCode().name());
228+
then(error.message()).isEqualTo(errorType.getMessage());
229+
then(error.data()).isEqualTo(additionalData);
230+
}
231+
}
232+
233+
// Test fixture
234+
record TestData(String name, int value) {}
235+
}

0 commit comments

Comments
 (0)