Skip to content

Commit 2087e24

Browse files
committed
Kotest
1 parent 07c8cdf commit 2087e24

File tree

3 files changed

+132
-135
lines changed

3 files changed

+132
-135
lines changed

build.gradle.kts

+14-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ plugins {
55
alias(libs.plugins.detekt)
66
alias(libs.plugins.versions)
77
alias(libs.plugins.serialization)
8+
jacoco
89
}
910

1011
group = "no.java.conf"
@@ -44,9 +45,7 @@ dependencies {
4445
implementation(libs.arrow.core)
4546
implementation(libs.kotlin.logging)
4647
implementation(libs.bundles.search)
47-
testImplementation(libs.ktor.server.test.host)
48-
testImplementation(libs.kotlin.test.junit)
49-
testImplementation(libs.mockk)
48+
testImplementation(libs.bundles.test)
5049
}
5150

5251
tasks.shadowJar {
@@ -61,4 +60,16 @@ tasks.shadowJar {
6160

6261
tasks.jar {
6362
enabled = false
63+
}
64+
65+
tasks.withType<Test>().configureEach {
66+
useJUnitPlatform()
67+
}
68+
69+
tasks.test {
70+
finalizedBy(tasks.jacocoTestReport)
71+
}
72+
73+
tasks.jacocoTestReport {
74+
dependsOn(tasks.test)
6475
}

gradle/libs.versions.toml

+28-21
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,55 @@
11

22
[versions]
3-
ktor-version = "3.0.1"
4-
kotlin-version = "2.1.0"
5-
logback-version = "1.5.12"
6-
prometheus-version = "1.14.1"
7-
gradle_versions_filter_version = "0.1.16"
3+
arrow_version = "1.2.4"
84
detekt_version = "1.23.7"
9-
kotlinter_version = "5.0.0"
5+
gradle_versions_filter_version = "0.1.16"
6+
kotest-version = "6.0.0.M1"
7+
kotlin-version = "2.1.0"
108
kotlin_logging_version = "7.0.0"
11-
arrow_version = "1.2.4"
12-
search_client_version = "2.3.2"
9+
kotlinter_version = "5.0.0"
1310
kotlinx_serialization_version = "1.7.3"
14-
node_version = "7.1.0"
11+
ktor-version = "3.0.1"
12+
logback-version = "1.5.12"
1513
mockk_version = "1.13.13"
14+
node_version = "7.1.0"
15+
prometheus-version = "1.14.1"
16+
search_client_version = "2.3.2"
1617

1718
[libraries]
1819
arrow-core = { group = "io.arrow-kt", name = "arrow-core", version.ref = "arrow_version" }
20+
1921
kotlin-logging = { group = "io.github.oshai", name = "kotlin-logging-jvm", version.ref = "kotlin_logging_version" }
22+
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx_serialization_version" }
23+
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor_version" }
24+
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor_version" }
25+
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor_version" }
26+
ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor_version" }
27+
ktor-serialization = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor_version" }
28+
ktor-server-call-id = { module = "io.ktor:ktor-server-call-id-jvm", version.ref = "ktor-version" }
29+
ktor-server-call-logging = { module = "io.ktor:ktor-server-call-logging-jvm", version.ref = "ktor-version" }
30+
ktor-server-cio = { module = "io.ktor:ktor-server-cio-jvm", version.ref = "ktor-version" }
2031
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation-jvm", version.ref = "ktor-version" }
2132
ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "ktor-version" }
22-
ktor-server-metrics-micrometer = { module = "io.ktor:ktor-server-metrics-micrometer-jvm", version.ref = "ktor-version" }
23-
micrometer-registry-prometheus = { module = "io.micrometer:micrometer-registry-prometheus", version.ref = "prometheus-version" }
24-
ktor-server-call-logging = { module = "io.ktor:ktor-server-call-logging-jvm", version.ref = "ktor-version" }
25-
ktor-server-call-id = { module = "io.ktor:ktor-server-call-id-jvm", version.ref = "ktor-version" }
2633
ktor-server-host-common = { module = "io.ktor:ktor-server-host-common-jvm", version.ref = "ktor-version" }
34+
ktor-server-metrics-micrometer = { module = "io.ktor:ktor-server-metrics-micrometer-jvm", version.ref = "ktor-version" }
2735
ktor-server-status-pages = { module = "io.ktor:ktor-server-status-pages-jvm", version.ref = "ktor-version" }
28-
ktor-server-cio = { module = "io.ktor:ktor-server-cio-jvm", version.ref = "ktor-version" }
2936
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback-version" }
37+
micrometer-registry-prometheus = { module = "io.micrometer:micrometer-registry-prometheus", version.ref = "prometheus-version" }
38+
search-client = { group = "com.jillesvangurp", name = "search-client", version.ref = "search_client_version" }
39+
3040
ktor-server-test-host = { module = "io.ktor:ktor-server-test-host-jvm", version.ref = "ktor-version" }
3141
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin-version" }
32-
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor_version" }
33-
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor_version" }
34-
ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor_version" }
35-
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor_version" }
36-
search-client = { group = "com.jillesvangurp", name = "search-client", version.ref = "search_client_version" }
37-
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx_serialization_version" }
38-
ktor-serialization = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor_version" }
42+
kotest = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest-version" }
43+
kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest-version" }
44+
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor-version" }
3945
mockk = { group = "io.mockk", name="mockk", version.ref = "mockk_version" }
4046

4147
[bundles]
4248
monitoring = ["ktor-server-metrics-micrometer", "micrometer-registry-prometheus", "ktor-server-call-id", "ktor-server-call-logging"]
4349
ktor-client = ["ktor-client-content-negotiation", "ktor-client-core", "ktor-client-logging", "ktor-client-cio"]
4450
serialization = ["ktor-serialization","kotlinx-serialization"]
4551
search = ["search-client"]
52+
test = ["ktor-server-test-host", "kotlin-test-junit", "kotest", "kotest-assertions", "ktor-client-mock", "mockk"]
4653

4754
[plugins]
4855
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" }
+90-111
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package no.java.conf
22

3+
import io.kotest.core.spec.style.FunSpec
34
import io.ktor.client.request.get
45
import io.ktor.client.statement.bodyAsText
56
import io.ktor.http.HttpStatusCode
7+
import io.ktor.server.testing.ApplicationTestBuilder
68
import io.ktor.server.testing.testApplication
79
import io.mockk.coEvery
810
import io.mockk.just
@@ -14,150 +16,127 @@ import no.java.conf.service.SearchService
1416
import no.java.conf.service.search.ElasticIndexer
1517
import no.java.conf.service.search.ElasticIngester
1618
import no.java.conf.service.search.ElasticSearcher
17-
import kotlin.test.Test
1819
import kotlin.test.assertEquals
1920

20-
class StateTest {
21-
@Test
22-
fun testNew() {
23-
val indexer = mockk<ElasticIndexer>()
24-
val ingester = mockk<ElasticIngester>()
25-
val searcher = mockk<ElasticSearcher>()
21+
class StateTest :
22+
FunSpec({
23+
test("test new") {
24+
testApplication {
25+
buildTestApplication(skipIndex = false)
2626

27-
val service = SearchService(indexer, ingester, searcher, false)
28-
29-
testApplication {
30-
application {
31-
configureSearchRouting(service)
32-
}
33-
34-
client.get("/api/search/state").apply {
35-
assertEquals(HttpStatusCode.OK, status)
36-
assertEquals(bodyAsText(), "NEW")
27+
client.get("/api/search/state").apply {
28+
assertEquals(HttpStatusCode.OK, status)
29+
assertEquals(bodyAsText(), "NEW")
30+
}
3731
}
3832
}
39-
}
4033

41-
@Test
42-
fun testMapped() {
43-
val indexer = mockk<ElasticIndexer>()
44-
val ingester = mockk<ElasticIngester>()
45-
val searcher = mockk<ElasticSearcher>()
34+
test("test mapped") {
35+
val indexer = mockk<ElasticIndexer>()
4636

47-
val service = SearchService(indexer, ingester, searcher, false)
37+
coEvery { indexer.recreateIndex(any()) } just runs
4838

49-
coEvery { indexer.recreateIndex(any()) } just runs
39+
testApplication {
40+
buildTestApplication(indexer = indexer, skipIndex = false) { service ->
41+
service.setup()
42+
}
5043

51-
runBlocking {
52-
service.setup()
53-
}
54-
55-
testApplication {
56-
application {
57-
configureSearchRouting(service)
58-
}
59-
60-
client.get("/api/search/state").apply {
61-
assertEquals(HttpStatusCode.OK, status)
62-
assertEquals(bodyAsText(), "MAPPED")
44+
client.get("/api/search/state").apply {
45+
assertEquals(HttpStatusCode.OK, status)
46+
assertEquals(bodyAsText(), "MAPPED")
47+
}
6348
}
6449
}
65-
}
6650

67-
@Test
68-
fun testIndexed() {
69-
val indexer = mockk<ElasticIndexer>()
70-
val ingester = mockk<ElasticIngester>()
71-
val searcher = mockk<ElasticSearcher>()
51+
test("test indexed") {
52+
val indexer = mockk<ElasticIndexer>()
53+
val ingester = mockk<ElasticIngester>()
7254

73-
val service = SearchService(indexer, ingester, searcher, false)
55+
coEvery { indexer.recreateIndex(any()) } just runs
56+
coEvery { ingester.ingest(any(), any()) } just runs
7457

75-
coEvery { indexer.recreateIndex(any()) } just runs
76-
coEvery { ingester.ingest(any(), any()) } just runs
58+
testApplication {
59+
buildTestApplication(indexer = indexer, ingester = ingester, skipIndex = false) { service ->
60+
service.setup()
61+
service.ingest(emptyList())
62+
}
7763

78-
runBlocking {
79-
service.setup()
80-
service.ingest(emptyList())
64+
client.get("/api/search/state").apply {
65+
assertEquals(HttpStatusCode.OK, status)
66+
assertEquals(bodyAsText(), "INDEXED")
67+
}
68+
}
8169
}
8270

83-
testApplication {
84-
application {
85-
configureSearchRouting(service)
86-
}
71+
test("test skip index new") {
72+
testApplication {
73+
buildTestApplication(skipIndex = true)
8774

88-
client.get("/api/search/state").apply {
89-
assertEquals(HttpStatusCode.OK, status)
90-
assertEquals(bodyAsText(), "INDEXED")
75+
client.get("/api/search/state").apply {
76+
assertEquals(HttpStatusCode.OK, status)
77+
assertEquals(bodyAsText(), "NEW")
78+
}
9179
}
9280
}
93-
}
9481

95-
@Test
96-
fun testSkipIndexNew() {
97-
val indexer = mockk<ElasticIndexer>()
98-
val ingester = mockk<ElasticIngester>()
99-
val searcher = mockk<ElasticSearcher>()
82+
test("test skip index mapped") {
83+
val indexer = mockk<ElasticIndexer>()
10084

101-
val service = SearchService(indexer, ingester, searcher, true)
85+
coEvery { indexer.recreateIndex(any()) } just runs
10286

103-
testApplication {
104-
application {
105-
configureSearchRouting(service)
106-
}
87+
testApplication {
88+
buildTestApplication(indexer = indexer, skipIndex = false) { service ->
89+
service.setup()
90+
}
10791

108-
client.get("/api/search/state").apply {
109-
assertEquals(HttpStatusCode.OK, status)
110-
assertEquals(bodyAsText(), "NEW")
92+
client.get("/api/search/state").apply {
93+
assertEquals(HttpStatusCode.OK, status)
94+
assertEquals(bodyAsText(), "MAPPED")
95+
}
11196
}
11297
}
113-
}
114-
115-
@Test
116-
fun testSkipIndexMapped() {
117-
val indexer = mockk<ElasticIndexer>()
118-
val ingester = mockk<ElasticIngester>()
119-
val searcher = mockk<ElasticSearcher>()
12098

121-
val service = SearchService(indexer, ingester, searcher, true)
99+
test("test skip index indexed") {
100+
val indexer = mockk<ElasticIndexer>()
101+
val ingester = mockk<ElasticIngester>()
122102

123-
runBlocking {
124-
service.setup()
125-
}
103+
coEvery { indexer.recreateIndex(any()) } just runs
104+
coEvery { ingester.ingest(any(), any()) } just runs
126105

127-
testApplication {
128-
application {
129-
configureSearchRouting(service)
130-
}
106+
testApplication {
107+
buildTestApplication(indexer = indexer, ingester = ingester, skipIndex = false) { service ->
108+
service.setup()
109+
service.ingest(emptyList())
110+
}
131111

132-
client.get("/api/search/state").apply {
133-
assertEquals(HttpStatusCode.OK, status)
134-
assertEquals(bodyAsText(), "MAPPED")
112+
client.get("/api/search/state").apply {
113+
assertEquals(HttpStatusCode.OK, status)
114+
assertEquals(bodyAsText(), "INDEXED")
115+
}
135116
}
136117
}
118+
})
119+
120+
private fun ApplicationTestBuilder.buildTestApplication(
121+
indexer: ElasticIndexer = mockk(),
122+
ingester: ElasticIngester = mockk(),
123+
searcher: ElasticSearcher = mockk(),
124+
skipIndex: Boolean = false,
125+
block: (suspend (service: SearchService) -> Unit)? = null,
126+
) {
127+
val service =
128+
SearchService(
129+
indexer = indexer,
130+
ingester = ingester,
131+
searcher = searcher,
132+
skipIndex = skipIndex
133+
)
134+
135+
runBlocking {
136+
block?.invoke(service)
137137
}
138138

139-
@Test
140-
fun testSkipIndexIndexed() {
141-
val indexer = mockk<ElasticIndexer>()
142-
val ingester = mockk<ElasticIngester>()
143-
val searcher = mockk<ElasticSearcher>()
144-
145-
val service = SearchService(indexer, ingester, searcher, true)
146-
147-
runBlocking {
148-
service.setup()
149-
service.ingest(emptyList())
150-
}
151-
152-
testApplication {
153-
application {
154-
configureSearchRouting(service)
155-
}
156-
157-
client.get("/api/search/state").apply {
158-
assertEquals(HttpStatusCode.OK, status)
159-
assertEquals(bodyAsText(), "INDEXED")
160-
}
161-
}
139+
application {
140+
configureSearchRouting(service)
162141
}
163142
}

0 commit comments

Comments
 (0)