すきま風

勉強したことのメモとか

JUnit5 で BDD

JUnit5のinner classを利用したBDD記法のサンプルです。

検証環境

software version
OS MacOS Mojave
Spring Boot 2.2.0.M4
Java Corretto-11.0.4.11.1
Kotlin 1.3.41
JUnit5 5.5.1

テストするクラスとシナリオ

Item classと、Itemを格納するCart classを用意します。 Cartの中に酒が含まれている場合、購入時に年齢認証が必要になります。

data class Item(
    val name: String,
    val price: Int,
    val isAlcohol: Boolean = false
)

data class Cart(
    private val items: MutableList<Item>
) {
    fun hasItem() = items.isNotEmpty()

    fun shouldConfirmAge() = items.any { it.isAlcohol }

    fun addItem(item: Item) {
        items += item
    }

    fun items() = items.toList()

    fun clear() {
        items.clear()
    }
}

テストコード

class CartTests {
    private val cart = Cart(mutableListOf())

    @Nested
    @DisplayName("空のカートを作成する")
    inner class GivenEmptyCart {
        @BeforeEach
        fun setUp() {
            cart.clear()
        }

        @DisplayName("カートは商品を持っていない")
        @Test
        fun thenHasItemIsFalse() {
            assertFalse(cart.hasItem())
        }

        @Nested
        @DisplayName("カートに商品を追加する")
        inner class WhenAddItem {
            @BeforeEach
            fun setUp() {
                cart.addItem(Item("Kotlin in action", 2000))
            }

            @DisplayName("カートは商品を持っている")
            @Test
            fun thenHasItemIsTrue() {
                assertTrue(cart.hasItem())
            }
        }

        @Nested
        @DisplayName("カートにビールを追加する")
        inner class WhenAddAlcohol {
            @BeforeEach
            fun setUp() {
                cart.addItem(Item("Beer", 300, isAlcohol = true))
            }

            @DisplayName("カートは商品を持っている")
            @Test
            fun thenHasItemIsTrue() {
                assertTrue(cart.hasItem())
            }

            @DisplayName("年齢確認が必要")
            @Test
            fun thenShouldConfirmAge() {
                assertTrue(cart.shouldConfirmAge())
            }
        }
    }
}

まとめ

BDD用のテストライブラリはいくつかありますが、それぞれ独自のルールがあるため意外と使いにくく、学習コストがかかる中で 慣れ親しんだJUnit記法でそのまま表現できるところが利点だと思います。