-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feature] menu 도메인 정의 및 테스트 작성 (#29)
* create menu entity * menu mother and test
- Loading branch information
Showing
4 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
src/main/kotlin/com/mjucow/eatda/domain/store/entity/Menu.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.mjucow.eatda.domain.store.entity | ||
|
||
import com.mjucow.eatda.domain.common.BaseEntity | ||
import jakarta.persistence.Column | ||
import jakarta.persistence.Entity | ||
import jakarta.persistence.FetchType | ||
import jakarta.persistence.JoinColumn | ||
import jakarta.persistence.ManyToOne | ||
import jakarta.persistence.Table | ||
|
||
@Entity | ||
@Table(name = "menu") | ||
class Menu( | ||
@JoinColumn(name = "store_id", updatable = false) | ||
@ManyToOne(fetch = FetchType.LAZY, optional = false) | ||
val store: Store, | ||
) : BaseEntity() { | ||
constructor( | ||
name: String, | ||
price: Int, | ||
imageAddress: String? = null, | ||
store: Store, | ||
) : this(store) { | ||
this.name = name | ||
this.price = price | ||
this.imageAddress = imageAddress | ||
} | ||
|
||
@Column(nullable = false) | ||
var name: String = "" | ||
set(value) { | ||
validateName(value) | ||
field = value.trim() | ||
} | ||
|
||
@Column(nullable = false) | ||
var price: Int = 0 | ||
set(value) { | ||
validatePrice(value) | ||
field = value | ||
} | ||
|
||
@Column(nullable = true) | ||
var imageAddress: String? = null | ||
set(value) { | ||
field = value?.also { validateImageAddress(it) } | ||
} | ||
|
||
private fun validateName(name: String) { | ||
require(name.isNotBlank() && name.length <= MAX_NAME_LENGTH) | ||
} | ||
|
||
private fun validatePrice(price: Int) { | ||
require(MIN_PRICE <= price && price % PRICE_UNIT == 0) | ||
} | ||
|
||
private fun validateImageAddress(imageAddress: String) { | ||
require(imageAddress.isNotBlank() && imageAddress.length <= MAX_IMAGE_ADDRESS_LENGTH) | ||
} | ||
|
||
companion object { | ||
const val MIN_PRICE = 100 | ||
const val PRICE_UNIT = 100 | ||
const val MAX_NAME_LENGTH = 31 | ||
const val MAX_IMAGE_ADDRESS_LENGTH = 255 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
-- liquibase formatted sql | ||
|
||
-- changeset liquibase:5 | ||
CREATE TABLE menu ( | ||
id bigserial NOT NULL PRIMARY KEY , | ||
name varchar(31) NOT NULL, | ||
price integer NOT NULL, | ||
image_address varchar(255) NULL, | ||
created_at timestamp NOT NULL DEFAULT NOW(), | ||
updated_at timestamp NOT NULL, | ||
store_id bigint NOT NULL REFERENCES store | ||
); |
140 changes: 140 additions & 0 deletions
140
src/test/kotlin/com/mjucow/eatda/domain/store/entity/MenuTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package com.mjucow.eatda.domain.store.entity | ||
|
||
import com.mjucow.eatda.domain.store.entity.objectmother.MenuMother | ||
import com.mjucow.eatda.domain.store.entity.objectmother.StoreMother | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.assertj.core.api.Assertions.catchThrowable | ||
import org.junit.jupiter.api.DisplayName | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.params.ParameterizedTest | ||
import org.junit.jupiter.params.provider.EmptySource | ||
import org.junit.jupiter.params.provider.NullSource | ||
import org.junit.jupiter.params.provider.ValueSource | ||
|
||
class MenuTest { | ||
@DisplayName("이름이 빈 값이라면 예외를 던진다") | ||
@ParameterizedTest | ||
@EmptySource | ||
fun test1(name: String) { | ||
// given | ||
val store = StoreMother.create() | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu(name = name, price = MenuMother.PRICE, store = store) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("이름이 길이가 최대길이보다 길면 예외를 던진다") | ||
@Test | ||
fun test2() { | ||
// given | ||
val store = StoreMother.create() | ||
val name = "a".repeat(Menu.MAX_NAME_LENGTH + 1) | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu(name = name, price = MenuMother.PRICE, store = store) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("가격이 최소 가격보다 작다면 예외를 던진다") | ||
@ParameterizedTest | ||
@ValueSource(ints = [Int.MIN_VALUE, -1, 0, 1, Menu.MIN_PRICE - 1]) | ||
fun test3(price: Int) { | ||
// given | ||
val store = StoreMother.create() | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu(name = MenuMother.NAME, price = price, store = store) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("가격이 단위 가격을 준수하지 않으면 예외를 던진다") | ||
@Test | ||
fun test4() { | ||
// given | ||
val store = StoreMother.create() | ||
val price = MenuMother.PRICE + Menu.PRICE_UNIT - 1 | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu(name = MenuMother.NAME, price = price, store = store) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("이미지 주소가 빈 값이라면 예외를 던진다") | ||
@ParameterizedTest | ||
@EmptySource | ||
fun test4(imageAddress: String) { | ||
// given | ||
val store = StoreMother.create() | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu( | ||
name = MenuMother.NAME, | ||
price = MenuMother.PRICE, | ||
imageAddress = imageAddress, | ||
store = store | ||
) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("이미지 주소가 최대 길이보다 길다면 예외를 던진다") | ||
@Test | ||
fun test5() { | ||
// given | ||
val store = StoreMother.create() | ||
val imageAddress = "a".repeat(Menu.MAX_IMAGE_ADDRESS_LENGTH + 1) | ||
|
||
// when | ||
val throwable = catchThrowable { | ||
Menu( | ||
name = MenuMother.NAME, | ||
price = MenuMother.PRICE, | ||
imageAddress = imageAddress, | ||
store = store | ||
) | ||
} | ||
|
||
// then | ||
assertThat(throwable).isNotNull() | ||
} | ||
|
||
@DisplayName("정상적인 값이라면 생성된다") | ||
@ParameterizedTest | ||
@NullSource | ||
@ValueSource(strings = [MenuMother.IMAGE_ADDRESS]) | ||
fun test6(imageAddress: String?) { | ||
// given | ||
val store = StoreMother.create() | ||
|
||
// when | ||
val menu = Menu( | ||
name = MenuMother.NAME, | ||
price = MenuMother.PRICE, | ||
imageAddress = imageAddress, | ||
store = store | ||
) | ||
|
||
// then | ||
assertThat(menu).isNotNull() | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/test/kotlin/com/mjucow/eatda/domain/store/entity/objectmother/MenuMother.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.mjucow.eatda.domain.store.entity.objectmother | ||
|
||
import com.mjucow.eatda.common.objectmother.EntityMother | ||
import com.mjucow.eatda.domain.store.entity.Menu | ||
|
||
object MenuMother : EntityMother<Menu>() { | ||
const val NAME = "menu" | ||
const val PRICE = 1000 | ||
const val IMAGE_ADDRESS = "/eatda/public/menu/232D8241-C6A9-4AD9-B0EA-56F6DD24BADF.jpg" | ||
|
||
override fun createFillInstance() = Menu( | ||
name = NAME, | ||
price = PRICE, | ||
imageAddress = IMAGE_ADDRESS, | ||
store = StoreMother.create() | ||
) | ||
|
||
override fun createDefaultInstance() = Menu( | ||
name = NAME, | ||
price = PRICE, | ||
store = StoreMother.create() | ||
) | ||
} |