全分insertではQuery Serviceと同じ手法が使えるため、差分insertについて説明をします。

まずは単純な社員(employee)について考えます。

classDiagram

class employee{
	UUID employee_id PK
	timestamp created_at
}

class employee_name{
	UUID employee_id FK
	text name
	timestamp created_at
}
employee <|-- employee_name

idテーブルがひとつ、valueテーブルがひとつという構造です。

はじめはテーブル単位でinsert、selectを行う処理を書き、後でそれをまとめてRepositoryを作ります。

EmployeeDaoを作る

DAO(Data Access Object、以降Daoと表記)とは、データを操作するためのオブジェクトのことです。

テーブルひとつに対し、Daoをひとつ作ります。

まずはEmployeeDaoを作ってみましょう。

private class EmployeeDaoTest {

    private val sut = EmployeeDao()

		@Test
    fun `insertしたデータがselectメソッドで検索できること`() {
        val dto = EmployeeDto(
            employeeId = UUID.fromString("34a1b832-2220-4075-a704-669c0e97cbbc"),
            createdAt = LocalDateTime.now(),
        )

        sut.insert(dto)

        val actual = sut.selectOrNull(dto.employeeId)

        assertEquals(dto,actual)
    }
}

テストコードをひとつ追加しました。

変数名に使っているsutとは、System Under Testの略でテスト対象システムのことを指しています。

どれがテスト対象になっているのかわかりやすいため、筆者は好んで使っています。

実装の詳細はライブラリーによって変わるためこれ以上立ち入りませんが、createdAtの精度はRDBMSによって変わるためこのテストが成功しない可能性があります。

その場合にはLocalDateTime#nowを直接使うのではなく、ラッパーを用意してそのラッパー内で時間の切り上げを行います。

では、もうひとつテストコードを追加してみましょう。

		@Test
    fun `同じデータがinsertされた場合は例外を投げること`() {
        val dto = EmployeeDto(
            employeeId = UUID.fromString("6b4635ba-b868-457b-9109-fe9fc4db1682"),
            createdAt = LocalDateTime.now(),
        )

        sut.insert(dto)
        
        assertThrows<IllegalStateException> {
            sut.insert(dto)
        }
    }

ここではIllegalStateExceptionを期待値としていますが、実際には一意制約違反の例外が発生します。