Skip to content

[✨feat] InternshipWorkingPeriod 구현 #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 26, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -16,4 +16,5 @@ enum class InternshipErrorCode(
INVALID_COMPANY_NAME_TOO_LONG(HttpStatus.BAD_REQUEST, "기업명은 64자 이하여야 합니다."),
INVALID_INTERNSHIP_TITLE_EMPTY(HttpStatus.BAD_REQUEST, "인턴십 제목은 비어 있을 수 없습니다."),
INVALID_INTERNSHIP_TITLE_TOO_LONG(HttpStatus.BAD_REQUEST, "인턴십 제목은 64자 이하여야 합니다."),
INVALID_WORKING_PERIOD(HttpStatus.BAD_REQUEST, "근무 기간은 1개월 이상이어야 합니다."),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.terning.server.kotlin.domain.internshipAnnouncement

import jakarta.persistence.Embeddable

@Embeddable
class InternshipWorkingPeriod private constructor(
val months: Int,
) {
init {
validatePositive(months)
}

fun toKoreanPeriod(): String = "${months}개월"

override fun equals(other: Any?): Boolean = this === other || (other is InternshipWorkingPeriod && months == other.months)

override fun hashCode(): Int = months

override fun toString(): String = toKoreanPeriod()

companion object {
private const val MINIMUM_MONTHS = 1

fun from(months: Int): InternshipWorkingPeriod = InternshipWorkingPeriod(months)

private fun validatePositive(months: Int) {
if (months < MINIMUM_MONTHS) {
throw InternshipException(InternshipErrorCode.INVALID_WORKING_PERIOD)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.terning.server.kotlin.domain.internshipAnnouncement

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class InternshipWorkingPeriodTest {
@Nested
@DisplayName("InternshipWorkingPeriod.from 메서드는")
inner class From {
@Test
@DisplayName("유효한 개월 수를 입력하면 객체를 생성한다")
fun `create instance when valid months given`() {
// given
val months = 3

// when
val period = InternshipWorkingPeriod.from(months)
Comment on lines +15 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순 궁금증에 여쭤봅니다!
아래 테스트 코드들에서는 그냥 정수를 넣어주고 있는데 해당 테스트 코드 케이스에서는 month라고 변수화를 해주고 있어서 혹시 장순님의 기준이 있는 건지 궁금했어요..!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 질문 감사합니다! 🙏
사실 이 부분은 명확한 기준이 있다기보다는,
"해당 값에 의미를 부여하고 싶을 때는 변수로 선언하고, 그렇지 않을 경우에는 인라인으로 작성하는 편"인데요,

이 테스트에서는 "유효한 month를 넘겼을 때"라는 케이스 자체가 핵심이라
months라는 이름으로 문맥을 명확히 드러내고 싶어서 변수화했던 것 같아요!
반대로 다른 테스트들에서는 특별한 의미 없이 단순히 값을 넘기기만 해서 인라인으로 처리했던 것 같습니다 😅

일관성 측면에서는 통일하는 게 더 좋을 것 같기도 해서,
이번 기회에 기준을 한 번 더 다듬어보는 계기로 삼아보겠습니다! 질문 감사합니다 🙇‍♂️✨


// then
assertThat(period.months).isEqualTo(months)
}

@Test
@DisplayName("0 이하의 개월 수를 입력하면 예외를 던진다")
fun `throw exception when months is zero or negative`() {
val exception =
assertThrows<InternshipException> {
InternshipWorkingPeriod.from(0)
}

assertThat(exception.errorCode).isEqualTo(InternshipErrorCode.INVALID_WORKING_PERIOD)
}
}

@Nested
@DisplayName("toKoreanPeriod 메서드는")
inner class ToKoreanPeriod {
@Test
@DisplayName("개월 수를 'N개월' 형태의 문자열로 반환한다")
fun `return correct korean period string`() {
// given
val period = InternshipWorkingPeriod.from(6)

// when
val result = period.toKoreanPeriod()

// then
assertThat(result).isEqualTo("6개월")
}
}
}