Skip to content

Commit

Permalink
test: 테스트 코드 추가 (mockito-kotlin 라이브러리 추가)
Browse files Browse the repository at this point in the history
  • Loading branch information
gusah009 committed Feb 24, 2024
1 parent 6d87200 commit 1b8404f
Show file tree
Hide file tree
Showing 8 changed files with 327 additions and 1 deletion.
4 changes: 4 additions & 0 deletions kotlin-christmas/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ repositories {

dependencies {
implementation("com.github.woowacourse-projects:mission-utils:1.1.0")
/**
* mockito를 사용하면 any! 타입이 반환되어 NPE가 터짐. 모킹을 너무 사용하고 싶기 때문에 라이브러리 추가...
*/
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")
}

java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ enum class EventPolicy {
private fun isInEventDate(userOrderInfo: UserOrderInfo) =
userOrderInfo.estimatedVisitDate.year == 2023 && userOrderInfo.estimatedVisitDate.month == Month.DECEMBER

protected abstract fun isOwnSupported(userOrderInfo: UserOrderInfo): Boolean
internal abstract fun isOwnSupported(userOrderInfo: UserOrderInfo): Boolean

abstract fun getBenefit(userOrderInfo: UserOrderInfo): EventType

Expand Down
20 changes: 20 additions & 0 deletions kotlin-christmas/src/test/kotlin/christmas/badge/BadgeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package christmas.badge

import christmas.model.Price
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class BadgeTest {
@Test
fun `가격에 맞는 뱃지가 나와야 한다`() {
assertThat(Badge.of(Price(0))).isEqualTo(null)
assertThat(Badge.of(Price(3000))).isEqualTo(null)
assertThat(Badge.of(Price(5000))).isEqualTo(Badge.별)
assertThat(Badge.of(Price(8000))).isEqualTo(Badge.별)
assertThat(Badge.of(Price(10000))).isEqualTo(Badge.트리)
assertThat(Badge.of(Price(15000))).isEqualTo(Badge.트리)
assertThat(Badge.of(Price(20000))).isEqualTo(Badge.산타)
assertThat(Badge.of(Price(20001))).isEqualTo(Badge.산타)
assertThat(Badge.of(Price(1_000_000))).isEqualTo(Badge.산타)
}
}
102 changes: 102 additions & 0 deletions kotlin-christmas/src/test/kotlin/christmas/event/EventPolicyTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package christmas.event

import christmas.model.Price
import christmas.model.UserOrderInfo
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import java.time.LocalDate

class EventPolicyTest {

@Nested
inner class GiveawayEventPolicyTest {

val giveawayEventPolicy = EventPolicy.GiveawayEventPolicy

@Test
fun `증정 이벤트는 총 금액이 120,000원 이상이면 제공한다`() {
val userOrderInfo1 = mock<UserOrderInfo> {
on { totalPrice } doReturn Price(0)
}
assertThat(giveawayEventPolicy.isOwnSupported(userOrderInfo1)).isFalse

val userOrderInfo2 = mock<UserOrderInfo> {
on { totalPrice } doReturn Price(119_999)
}
assertThat(giveawayEventPolicy.isOwnSupported(userOrderInfo2)).isFalse

val userOrderInfo3 = mock<UserOrderInfo> {
on { totalPrice } doReturn Price(120_000)
}
assertThat(giveawayEventPolicy.isOwnSupported(userOrderInfo3)).isTrue

val userOrderInfo4 = mock<UserOrderInfo> {
on { totalPrice } doReturn Price(200_000)
}
assertThat(giveawayEventPolicy.isOwnSupported(userOrderInfo4)).isTrue
}
}

@Nested
inner class ChristmasDiscountPolicyTest {

val christmasDiscountPolicy = EventPolicy.ChristmasDiscountPolicy

@Test
fun `크리스마스 디데이 할인은 12월 25일 이전이면 제공한다`() {
val userOrderInfo1 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 1)
}
assertThat(christmasDiscountPolicy.isOwnSupported(userOrderInfo1)).isTrue

val userOrderInfo2 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 25)
}
assertThat(christmasDiscountPolicy.isOwnSupported(userOrderInfo2)).isTrue

val userOrderInfo3 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 26)
}
assertThat(christmasDiscountPolicy.isOwnSupported(userOrderInfo3)).isFalse

val userOrderInfo4 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 31)
}
assertThat(christmasDiscountPolicy.isOwnSupported(userOrderInfo4)).isFalse
}

@Test
fun `크리스마스 디데이 할인은 하루가 지날 때마다 1000원씩 증가한 할인을 제공한다`() {
val userOrderInfo1 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 1)
}
assertThat(christmasDiscountPolicy.getBenefit(userOrderInfo1)).isInstanceOf(EventType.Discount::class.java)
assertThat((christmasDiscountPolicy.getBenefit(userOrderInfo1) as EventType.Discount).price)
.isEqualTo(Price(1000))

val userOrderInfo2 = mock<UserOrderInfo> {
on { estimatedVisitDate } doReturn LocalDate.of(2023, 12, 25)
}
assertThat(christmasDiscountPolicy.getBenefit(userOrderInfo2)).isInstanceOf(EventType.Discount::class.java)
assertThat((christmasDiscountPolicy.getBenefit(userOrderInfo2) as EventType.Discount).price)
.isEqualTo(Price(3400))
}
}

// 중략 ...
@Nested
inner class WeekdayDiscountPolicyTest {
}

@Nested
inner class WeekendDiscountPolicyTest {
}

@Nested
inner class SpecialDiscountPolicyTest {
}

}
45 changes: 45 additions & 0 deletions kotlin-christmas/src/test/kotlin/christmas/model/PriceTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package christmas.model

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class PriceTest {

@Test
fun times() {
assertThat(Price(100) * 10).isEqualTo(Price(1000))
assertThat(Price(250) * 10).isEqualTo(Price(2500))
}

@Test
fun plus() {
assertThat(Price(100) + Price(10)).isEqualTo(Price(110))
assertThat(Price(250) + Price(10)).isEqualTo(Price(260))
}

@Test
fun minus() {
assertThat(Price(100) - Price(10)).isEqualTo(Price(90))
assertThat(Price(250) - Price(10)).isEqualTo(Price(240))
}

@Test
fun compareTo() {
assertThat(Price(100) > Price(10)).isTrue
assertThat(Price(250) < Price(10)).isFalse
assertThat(Price(100) == Price(100)).isTrue
assertThat(Price(100) == Price(50)).isFalse

assertThat(Price(100) > 10).isTrue
assertThat(Price(250) < 10).isFalse
assertThat(Price(100) >= 100).isTrue
assertThat(Price(100) <= 50).isFalse
}

@Test
fun `toMinusString을 사용하면 0원을 제외한 나머지 금액은 마이너스가 붙어야 한다`() {
assertThat(Price(0).toMinusString()).isEqualTo("0원")
assertThat(Price(100).toMinusString()).isEqualTo("-100원")
assertThat(Price(12345).toMinusString()).isEqualTo("-12,345원")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package christmas.model

import christmas.event.EventType
import christmas.menu.Menu
import christmas.menu.MenuWithCount
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

class UserBenefitInfoTest {

@Test
fun getGiveawayTest() {
val userBenefitInfo1 = UserBenefitInfo(
listOf(
EventType.Giveaway(MenuWithCount(Menu.양송이스프, 1), anyString()),
EventType.Discount(Price(1000), "anyString"), // stub for testing
)
)
assertThat(userBenefitInfo1.giveaway).isNotNull
assertThat(userBenefitInfo1.giveaway!!.menuWithCount).isEqualTo(MenuWithCount(Menu.양송이스프, 1))

val userBenefitInfo2 = UserBenefitInfo(
listOf(
EventType.Discount(Price(1000), "anyString"), // stub for testing
)
)
assertThat(userBenefitInfo2.giveaway).isNull()
}

@Test
fun getTotalBenefitAmountTest() {
val menu = mock<Menu> {
on { price } doReturn Price(1000)
}
val userBenefitInfo = UserBenefitInfo(
listOf(
EventType.Giveaway(MenuWithCount(menu, 3), "anyString"), // 1000 * 3 == 3000원
EventType.Discount(Price(500), "anyString"),
EventType.Discount(Price(70), "anyString"),
)
)

assertThat(userBenefitInfo.totalBenefitAmount).isEqualTo(Price(3570))
}

@Test
fun getTotalDiscountAmountTest() {

val menu = mock<Menu> {
on { price } doReturn Price(1000)
}
val userBenefitInfo = UserBenefitInfo(
listOf(
EventType.Giveaway(MenuWithCount(menu, 3), "anyString"),
EventType.Discount(Price(500), "anyString"),
EventType.Discount(Price(70), "anyString"),
)
)

assertThat(userBenefitInfo.totalDiscountAmount).isEqualTo(Price(570))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package christmas.model

import christmas.menu.Menu
import christmas.menu.MenuType
import christmas.menu.MenuWithCount
import christmas.util.assertContains
import christmas.validation.ChristmasException
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows

class UserOrderInfoTest {
@Nested
inner class VisitDayTest {
@Test
fun `visitday는 1일 ~ 31일 안이어야 한다`() {
assertThrows<ChristmasException> { UserOrderInfo.VisitDay(0) }
assertDoesNotThrow { UserOrderInfo.VisitDay(1) }
assertDoesNotThrow { UserOrderInfo.VisitDay(31) }
assertThrows<ChristmasException> { UserOrderInfo.VisitDay(32) }
}
}

@Nested
inner class UserOrderMenuTest {
@Test
fun `userOrderMenu 개수는 총 20개를 넘으면 안된다`() {
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu(listOf(generateWithoutDrink(1)))
}
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu(listOf(generateWithoutDrink(20))) // 20개
}
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu((1..19).map { generateWithoutDrink(1) }) // 19개
}
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu((1..10).map { generateWithoutDrink(2) }) // 20개
}
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu((1..4).map { generateWithoutDrink(5) }) // 20개
}

assertThrows<ChristmasException>("totalMenuCount는 20개를 넘을 수 없습니다.") {
UserOrderInfo.UserOrderMenu((1..21).map { generateWithoutDrink(1) }) // 21개
}
assertThrows<ChristmasException>("totalMenuCount는 20개를 넘을 수 없습니다.") {
UserOrderInfo.UserOrderMenu((1..11).map { generateWithoutDrink(2) }) // 22개
}
assertThrows<ChristmasException>("totalMenuCount는 20개를 넘을 수 없습니다.") {
UserOrderInfo.UserOrderMenu((1..8).map { generateWithoutDrink(3) }) // 24개
}
assertThrows<ChristmasException>("totalMenuCount는 20개를 넘을 수 없습니다.") {
UserOrderInfo.UserOrderMenu(listOf(generateWithoutDrink(21))) // 21개
}
}

@Test
fun `음료만 주문하면 안된다`() {
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu(listOf(generateWithoutDrink()))
}
assertDoesNotThrow {
UserOrderInfo.UserOrderMenu(listOf(generateWithoutDrink(), generateDrink()))
}

for (i in 1..19) {
assertThrows<ChristmasException> {
UserOrderInfo.UserOrderMenu((1..i).map { generateDrink() })
}.message.assertContains("음료만 주문할 수 없습니다.")
}
}

/**
* 이것도 모킹하면 더 좋지만 체력 이슈로 패스
*/
private fun generateWithoutDrink(count: Int = 1) =
MenuWithCount(Menu.entries.filter { it.menuType != MenuType.Drink }.random(), count)

private fun generateDrink() = MenuWithCount(Menu.entries.filter { it.menuType == MenuType.Drink }.random(), 1)

}
}
6 changes: 6 additions & 0 deletions kotlin-christmas/src/test/kotlin/christmas/util/TestUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package christmas.util

import org.assertj.core.api.AbstractStringAssert
import org.assertj.core.api.Assertions

fun String.assertContains(message: String): AbstractStringAssert<*> = Assertions.assertThat(this).contains(message)

0 comments on commit 1b8404f

Please sign in to comment.