feat: implement application for testing
This commit is contained in:
parent
79dc26877e
commit
29a8e834b9
@ -33,6 +33,10 @@ dependencies {
|
|||||||
runtimeOnly("com.h2database:h2")
|
runtimeOnly("com.h2database:h2")
|
||||||
runtimeOnly("com.mysql:mysql-connector-j")
|
runtimeOnly("com.mysql:mysql-connector-j")
|
||||||
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
|
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
|
||||||
|
|
||||||
|
|
||||||
|
testImplementation("io.mockk:mockk:1.14.4")
|
||||||
|
testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
class DataSourceLookupController(
|
||||||
|
private val properties: DataSourceProperties,
|
||||||
|
) {
|
||||||
|
|
||||||
|
@GetMapping("/dataSource")
|
||||||
|
fun lookup(): DataSourceInfoResponse = DataSourceInfoResponse(
|
||||||
|
properties.url,
|
||||||
|
properties.username,
|
||||||
|
properties.password,
|
||||||
|
properties.driverClassName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DataSourceInfoResponse(
|
||||||
|
val url: String,
|
||||||
|
val username: String,
|
||||||
|
val password: String,
|
||||||
|
val driverClassName: String,
|
||||||
|
)
|
||||||
52
src/main/kotlin/com/sangdol/demo/DemoController.kt
Normal file
52
src/main/kotlin/com/sangdol/demo/DemoController.kt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/demo")
|
||||||
|
class DemoController(
|
||||||
|
private val demoService: DemoService
|
||||||
|
) {
|
||||||
|
@GetMapping
|
||||||
|
fun findAll(): List<FindResponse> = demoService.findAll()
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
fun findById(
|
||||||
|
@PathVariable id: Long
|
||||||
|
): FindResponse = demoService.findById(id)
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun create(
|
||||||
|
@RequestBody request: CreateRequest
|
||||||
|
): CreateResponse = demoService.create(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class CreateRequest(
|
||||||
|
val name: String,
|
||||||
|
val age: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun CreateRequest.toEntity(): DemoEntity = DemoEntity(
|
||||||
|
name = this.name,
|
||||||
|
age = this.age
|
||||||
|
)
|
||||||
|
|
||||||
|
data class CreateResponse(
|
||||||
|
val id: Long,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun DemoEntity.toCreateResponse(): CreateResponse = CreateResponse(
|
||||||
|
id = this.id ?: throw IllegalStateException("ID not generated"),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class FindResponse(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val age: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
fun DemoEntity.toFindResponse(): FindResponse = FindResponse(
|
||||||
|
id = this.id ?: throw IllegalStateException("ID not generated"),
|
||||||
|
name = this.name,
|
||||||
|
age = this.age
|
||||||
|
)
|
||||||
20
src/main/kotlin/com/sangdol/demo/DemoEntity.kt
Normal file
20
src/main/kotlin/com/sangdol/demo/DemoEntity.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity
|
||||||
|
import jakarta.persistence.GeneratedValue
|
||||||
|
import jakarta.persistence.GenerationType
|
||||||
|
import jakarta.persistence.Id
|
||||||
|
import jakarta.persistence.Table
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "demo")
|
||||||
|
class DemoEntity(
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
var id: Long? = null,
|
||||||
|
|
||||||
|
var name: String,
|
||||||
|
var age: Int,
|
||||||
|
)
|
||||||
|
|
||||||
6
src/main/kotlin/com/sangdol/demo/DemoRepository.kt
Normal file
6
src/main/kotlin/com/sangdol/demo/DemoRepository.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
interface DemoRepository : JpaRepository<DemoEntity, Long> {
|
||||||
|
}
|
||||||
26
src/main/kotlin/com/sangdol/demo/DemoService.kt
Normal file
26
src/main/kotlin/com/sangdol/demo/DemoService.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class DemoService(
|
||||||
|
private val demoRepository: DemoRepository
|
||||||
|
) {
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
fun findAll(): List<FindResponse> = demoRepository.findAll()
|
||||||
|
.map { it.toFindResponse() }
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
fun findById(id: Long): FindResponse = demoRepository.findByIdOrNull(id)
|
||||||
|
?.toFindResponse()
|
||||||
|
?: throw IllegalArgumentException("Entity with id: $id not exist")
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun create(
|
||||||
|
@RequestBody request: CreateRequest
|
||||||
|
): CreateResponse = demoRepository.save(request.toEntity())
|
||||||
|
.toCreateResponse()
|
||||||
|
}
|
||||||
8
src/main/resources/application-deploy.yml
Normal file
8
src/main/resources/application-deploy.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
driver-class-name: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}
|
||||||
|
url: ${SPRING_DATASOURCE_URL}
|
||||||
|
username: ${SPRING_DATASOURCE_USERNAME}
|
||||||
|
password: ${SPRING_DATASOURCE_PASSWORD}
|
||||||
|
|
||||||
|
|
||||||
15
src/main/resources/application-local.yml
Normal file
15
src/main/resources/application-local.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:h2:mem:test
|
||||||
|
username: sa
|
||||||
|
password:
|
||||||
|
driver-class-name: org.h2.Driver
|
||||||
|
jpa:
|
||||||
|
database-platform: org.hibernate.dialect.H2Dialect
|
||||||
|
show-sql: true
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
|
h2:
|
||||||
|
console:
|
||||||
|
enabled: true
|
||||||
@ -1,3 +1,12 @@
|
|||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: argo-vault-demo
|
name: argo-vault-demo
|
||||||
|
|
||||||
|
profiles:
|
||||||
|
active: ${SPRING_PROFILE:local}
|
||||||
|
|
||||||
|
jpa:
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: none
|
||||||
|
defer-datasource-initialization: true
|
||||||
|
open-in-view: false
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.sangdol.demo
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class DemoApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun contextLoads() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
43
src/test/kotlin/com/sangdol/demo/DemoServiceTest.kt
Normal file
43
src/test/kotlin/com/sangdol/demo/DemoServiceTest.kt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package com.sangdol.demo
|
||||||
|
|
||||||
|
import io.kotest.assertions.assertSoftly
|
||||||
|
import io.kotest.assertions.throwables.shouldThrow
|
||||||
|
import io.kotest.core.spec.style.BehaviorSpec
|
||||||
|
import io.kotest.matchers.shouldBe
|
||||||
|
import io.kotest.matchers.shouldNotBe
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
|
||||||
|
internal class DemoServiceTest : BehaviorSpec({
|
||||||
|
|
||||||
|
val demoRepository: DemoRepository = mockk()
|
||||||
|
val demoService = DemoService(demoRepository)
|
||||||
|
|
||||||
|
Given("Entity를 ID로 조회할 때") {
|
||||||
|
val id: Long = 1L
|
||||||
|
|
||||||
|
When("입력된 ID로 조회되는 결과가 없다면") {
|
||||||
|
every { demoRepository.findByIdOrNull(id) } returns null
|
||||||
|
|
||||||
|
Then("IllegalArgumentException이 발생한다.") {
|
||||||
|
shouldThrow<IllegalArgumentException> { demoService.findById(id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
When("입력된 ID로 조회되는 결과가 있다면") {
|
||||||
|
every { demoRepository.findByIdOrNull(id) } returns DemoEntity(id, "hello kotlin", 20)
|
||||||
|
|
||||||
|
Then("정상적으로 반환된다.") {
|
||||||
|
val result: FindResponse = demoService.findById(id)
|
||||||
|
result shouldNotBe null
|
||||||
|
|
||||||
|
assertSoftly(result) {
|
||||||
|
this.id shouldBe id
|
||||||
|
this.name shouldBe "hello kotlin"
|
||||||
|
this.age shouldBe 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user