一個現代化、雲原生的框架一定要考慮到測試,有足夠的測試才能讓應用在改版與升版時更有保證。Quarkus 整合了 JUnit5 讓我們可以很容易的寫出測試的程式碼
先來看一眼測試 REST endpoint,這裡是整合了 Rest Assured 與 Kotlin 的 DSL。 可以用 Gherkin 的風格來撰寫測試,也接近 user story 的表達。
今天的程式已經放置在 GitHub
@Test
fun `test list all`() {
Given {
contentType(ContentType.JSON)
} When {
get("/films")
} Then {
statusCode(200)
body("title", `is`(listOf("A New Hope", "Return"...)))
}
}
這樣的表達方式會比 Java 版本的 Rest Assured 語意更清楚
測試的程式碼都會在專案的 src/test/kotlin
,前幾天的 sample project 都有自帶一個 test 的 stub code : GreetingResourceTest.kt。可以看到要在 test class 打上 @QuarkusTest
及 Method 打上 @Test
@QuarkusTest
class GreetingResourceTest {
@Test
fun testHelloEndpoint() {
given()
.`when`().get("/hello")
.then()
.statusCode(200)
.body(`is`("Hello from RESTEasy Reactive"))
}
}
所以我們可以 copy 這個 class, rename成我們要的 filmResoruceTest.kt 。這裡我有另外用 test startup event 先塞了三份資料,所以get list all 時預期會抓出三個name
@Test
fun `test list all`() {
Given {
// 一定要加,不然會噴 415
contentType(ContentType.JSON)
} When {
// http get 的位置
get("/films")
} Then {
// Assertion 200 return
statusCode(200)
// 回來的 json array 有三個,裡頭的 title 各是...
body("title", `is`(listOf("A New Hope", "The Empire Strikes Back", "Return Of The Jedi")))
}
}
打上 @TestMethodOrder
可以讓測試照指定的順序執行
@QuarkusTest
@TestMethodOrder(value = MethodOrderer.OrderAnnotation::class)
例如我們要先新增,然後修改最後刪除就可以這樣寫
@Test
@Order(1)
fun `test add`() {
....
}
@Test
@Order(2)
fun `test update after add`() {
....
}
@Test
@Order(3)
fun `test delete`() {
....
}
新增一個 maven run : test 就可以執行測試
由 console 可以看到 quarkus 幫我們起了一個 mongodb, 並且將設定指過去。這個這測試的ap 會起在 8081。
剛剛都只講到從 REST endpoint 進去測,其實我們也可以直接 Inject Quarkus 所管理的 bean 來測。因為要測的大部份是 suspend function, 這裡要用 runBlocking 包起來才能編譯
@QuarkusTest
class FilmRepositoryTest {
@Inject
lateinit var filmRepository: FilmRepository
@Test
fun `test count`() {
runBlocking {
filmRepository.count().awaitSuspending()
.let { assertEquals(3, it) }
}
}
}