728x90
반응형
sealed class
sealed class 를 사용하여 하위 클래스의 유형을 제한하고, 안전하고 명확하게 관리하려는 목적.
상속 가능한 클래스 계층을 제한할 때 사용함.
- 특징
- 제한된 상속: sealed class 를 상속할 수 있는 클래스는 같은 파일 내에서만 정의될 수 있다.
- when 문에서 모든 하위 클래스를 컴파일 시점에 확인할 수 있어 안전한 타입 검사가 가능하다.
@Hidden
- OpenAPI(Swagger) 에서 해당 필드를 문서화하지 않고 숨기기 위해 사용함.
- 비즈니스 로직에서 사용되지만 API 사용자에게 노출할 필요가 없는 내부 구현 세부 사항인 경우 어노테이션을 사용해 숨김.
@JsonIgnore
- Jackson 라이브러리가 해당 필드를 JSON 직렬화/역직렬화 과정에서 무시하도록 함.
- API 요청 또는 응답에 포함되지 않기 위해서 사용함.
- 내부적으로 동작을 제어하기 위한 값일 뿐, 외부 클라이언트가 제공하거나 볼 필요가 없는 데이터일 경우 제외함.
필드를 숨긴 이유는 이 값이 내부 구현을 위한 로직일 뿐, 외부 API 사용자에게 노출할 필요가 없기 때문임.
class DTO {
sealed class Request(
@Hidden
@JsonIgnore
val type: PlatformType,
)
data class ARequest(
val code: String,
val aId: String,
) : Request(PlatformType.A)
data class MetaRequest(
val token: String,
val bId: String,
) : Request(PlatformType.B)
}
enum class PlatformType(
val description: String,
) {
A("---") {
override fun existsObjectiveType(objectiveType: ObjectiveType) =
listOf(ObjectiveType.TRAFFIC).contains(objectiveType)
},
B("+++") {
override fun existsObjectiveType(objectiveType: ObjectiveType) =
listOf(ObjectiveType.TRAFFIC).contains(objectiveType)
}
;
// 공통 인터페이스 강제, 추상화 및 다형성
// - abstract 는 서브클래스 또는 Enum 상수에서 반드시 특정 메서드를 구현하도록 강제 해야함.
abstract fun existsObjectiveType(objectiveType: ObjectiveType): Boolean
}
- 사용 예시
PlatformType.A.existsObjectiveType(ObjectiveType.TRAFFIC) // true PlatformType.B.existsObjectiveType(ObjectiveType.OTHER) // false
mockk
relaxed = true
mockk<ObjectMapper>() != mockk<ObjectMapper>(relaxed = true)
- 기본 동작 및 반환 타입과 관련이 있음.
- relaxed = true 로 설정하는 경우, mockk 에서 모든 메서드 호출에 대해 기본 값을 반환하도록 설정함
- 예상치 못한 타입 캐스팅 문제 발생 가능성 있음.
- java.lang.ClassCastException: class java.lang.Object cannot be cast to class...
every 제네릭 타입 처리 방식
every { objectMapper.readValue(redis, any<TypeReference<AdvertiserAuthDTO.Response>>()) } returns user
- any: 객체의 어떤 인스턴스도 허용한다는 의미.
- TypeReference: Jackson이 제네릭 타입의 데이터를 매핑할 때 사용하는 클래스.
- 런타임에 구체적인 제네릭 타입 정보를 유지함.
every { objectMapper.readValue<AdvertiserAuthDTO.Response>(redis) } returns user
- Kotlin 의 제네릭을 직접 사용하는 방식.
- Kotlin 은 기본적으로 제네릭 타입 정보를 컴파일 시점에만 유지하고, 런타임에는 해당 정보를 제거함.
- Jackson 은 런타임 시점에 제네릭 정보를 필요로 하는데, 이 방식에서는 TypeReference 가 없으므로 Jackson 이 런타임 타입을 정확히 알 수 없음.
readValue<AdvertiserAuthDTO.Response>
는 리플렉션을 사용한 내부 호출을 포함할 수 있는데, mockk 는 리플렉션 기반의 호출을 제대로 mock 하지 못할 수 있음.- mockk 가 호출을 인식하지 못해 MockException 발생.
728x90
반응형
'Blog > TIL' 카테고리의 다른 글
2025-01-16 (목) (0) | 2025.01.16 |
---|---|
2025-01-15 (수) (0) | 2025.01.15 |
2025-01-13 (월) (1) | 2025.01.13 |
2025-01-10 (금) (1) | 2025.01.10 |
2025-01-09 (목) (0) | 2025.01.09 |
댓글