why
@Test fun `指定した年齢未満のPersonsを取得する`() { MockKAnnotations.init(this) val allPersons = mockk<Persons>() every { port.getAllPersons() } returns allPersons val age = mockk<Age>() val expected = mockk<Persons>() every { allPersons.filterByLessThan(age) } returns expected target.getPersonsLessThanByAge(age) shouldBeEqualTo expected }
前回は Usecase で引数の数値未満の年齢の人間を取ってくるメソッドの UT を作った。
これは Gateway から取ってきた全ての Persons で、ドメインメソッドを呼び出し、結果が every で入ったドメインメソッドの返り値になっていることだけをテストしている。
これは Domain のメソッドの呼び出しがされるかどうかのテストまでしかしていない。
Domain のメソッドの動作のテストをするためには、Domain の UT を別に作る必要が有る。
Domain の実装を見る
Domain の実装は
data class Persons(val list: List<Person>) { fun filterByLessThan(age: Age): Persons { return Persons(this.list.filter { it.isLessThan(age) }) } } data class Person(val name: Name, val age: Age) { fun isLessThan(age: Age): Boolean { return this.age.isLessThan(age) } } data class Name(val value: String) data class Age(val value: Int) { fun isLessThan(other: Age): Boolean { return this.value < other.value } }
- Persons
- Person
- Age
- isLessThan
と言う構造になっていて、Age のデータクラスに実際の処理が入っている。
Domain の UT を作る
testImplementation("org.amshove.kluent:kluent:1.68") testImplementation("io.mockk:mockk:1.13.2")
kluent と mockk を Domain にも追加
@Test fun `受け取ったAge未満のPersonsを返す`() { val target = Persons(listOf( Person(Name("Taro"),Age(10)), Person(Name("Jiro"),Age(7)), Person(Name("Saburo"),Age(5)), )) val actual = target.filterByLessThan(Age(7)) val expected = Persons(listOf( Person(Name("Saburo"),Age(5)), )) actual shouldBeEqualTo expected }
実際に返ってくるような 10,7,5 歳のデータが入った Persons を用意
これをターゲットとして filterByLessThan が使われた後
期待値の 5 歳のデータのみがはいった Persons になることをテストする
Rest で UT を作る
エンドポイントにリクエストされた結果のテストは外部からやる。
なので Rest の UT では Domain から JSON への変換のテストだけをする。
他と同様に mockk と kluent を入れて
internal class PersonResourceKtTest { @Test fun `PersonsをPersonJsonのリストに変換する`() { val target = Persons(listOf( Person(Name("Taro"),Age(10)), Person(Name("Jiro"),Age(7)), )) val actual = target.toJson() val expected = PersonsJson( listOf( PersonJson("Taro", 10), PersonJson("Jiro", 7), ) ) actual shouldBeEqualTo expected } }
Person ドメインのリストである Persons を
PersonJson のリストである PersonsJson の形に変更できているかをテストする。
これまでの UT のまとめ
Driver
外部 API へのリクエストや DB へのアクセス。
E2E を流した時にテストされるので十分なので UT は必要ない。
Gateway
Driver から返ってきた Entity の Domain への変換。
返ってきたデータの Usecase に応じたフィルターなど。
これらを Driver からの返り値を擬似的に決めて
最終的に指定の Domain の想定するフィルター後などの値になっているかをテストする。
Port
穴にテストはない。
Usecase
Gateway を呼び出すだけのテストをする
関数本体を呼び出した時に、port から gateway が呼ばれているかをテストする。
Rest
URL からのアクセスで何が動くかはテストしない。
URL へのアクセスで DB や 外部への POST が飛ぶのは、E2E でテストされるからだ。
内部の Domain 型と 外部用の JSON 型の変換をテストする。
以上。
Top comments (0)