$30 off During Our Annual Pro Sale. View Details »

テストから始めるKotlin導入

futabooo
July 12, 2017

 テストから始めるKotlin導入

futabooo

July 12, 2017
Tweet

More Decks by futabooo

Other Decks in Technology

Transcript

  1. Start Kotlin with Test
    ςετ͔Β࢝ΊΔKotlinಋೖ

    View Slide

  2. 2
    About me
    4FOJPS&OHJOFFS4DSVN.BTUFSBUFVSFLB *OD
    +BWB ,PUMJO (PMBOH 5ZQF4DSJQU "OHVMBS+4
    'BOUBTZ&BSUI;FSP T$3:FE
    GVUBCPPP
    ɹɹɹೋ઒ ོߒʢTakahiro Futagawaʣ

    View Slide

  3. 3
    About eureka
    ैۀһ਺
    ໊ʢฏۉ೥ྸࡀʣ
    ࣄۀ಺༰
    ࣗࣾαʔϏεاըɾ։ൃɾӡӦ
    1BJST
    $PVQMFT
    ձࣾ֓ཁ

    View Slide

  4. 'BDFCPPLΛར༻ͨ͠
    ࿀Ѫɾࠗ׆ϚονϯάαʔϏε
    ྦྷܭձһ਺
    500ສ

    ಥഁ͠·ͨ͠

    View Slide

  5. ΧοϓϧͷͨΊͷΞϓϦ
    ࠃ಺࠷େڃ
    400ສ
    μ΢ϯϩʔυ

    View Slide

  6. 6
    Pairs
    +BWB ,PUMJO
    %BHHFS
    0SNB
    0L)UUQ 3FUSPpU
    #VUUFS,OJGF %BUB#JOEJOH
    3Y+BWB 3Y,PUMJO FUD
    Android JP

    View Slide

  7. 7
    Couples
    +BWB
    "DUJWF"OESPJE
    7PMMFZ 0L)UUQ 3FUSPpU 4PDLFU*0
    3Y+BWB
    FUD
    Android

    View Slide

  8. Pairs Androidͷྺ࢙
    8

    View Slide

  9. 9
    େੲͷPairsAndroid

    View Slide

  10. 10
    ݱࡏͷPairsAndroid

    View Slide

  11. 11
    ࠷ۙϦχϡʔΞϧͨ͠Global൛

    View Slide

  12. 12
    –R. Kulawiec
    “े෼ʹൃୡͨ͠όά͸ͲΕ΋ɺػೳͱݟ෼͚͕͔ͭͳ͍”

    View Slide

  13. View Slide

  14. ʊਓਓਓਓਓਓਓਓਓਓਓਓਓਓʊ
    ʼɹॏཁͳػೳ͕࢖͑ͳ͍όάɹʻ
    ʉ̮̮̮̮̮̮̮̮̮̮̮̮̮̮ʉ

    View Slide

  15. ςετ͕ॻ͍ͯ͋Ε͹๷͛ͨ

    View Slide

  16. ςετ͕ॻ͚Δঢ়ଶͰ͸ͳ͔ͬͨ

    View Slide

  17. ςετ͕ॻ͖΍͍͢ߏ੒ʹมߋ͢Δ
    17

    View Slide

  18. 18
    ͍͔ͭͷPairsAndroid

    View Slide

  19. 19
    Before
    &OUJUZ%BP
    %BUBCBTF "1*
    $MJFOU
    "DUJWJUZ'SBHNFOU

    View Slide

  20. 20
    After
    Dao
    %BUBCBTF API
    Client
    Repository
    UseCase
    Presenter
    Activity / Fragment
    Service

    View Slide

  21. 21
    ৄࡉ
    https://speakerdeck.com/lvla/activitywogai-shan-sitahua

    View Slide

  22. Kotlinಋೖ
    22

    View Slide

  23. 23
    AndroidStudio
    Preferences > Plugins > Browse Repositories

    View Slide

  24. 24
    build.gradle
    buildscript {
    dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.3-2"
    }
    }
    allprojects {
    repositories {
    maven { url 'http://dl.bintray.com/ngsw-taro/maven' }
    maven { url 'https://jitpack.io' }
    }
    }

    View Slide

  25. 25
    app/build.gradle
    apply plugin: 'kotlin-android'
    dependencies {
    testCompile 'junit:junit:4.12'
    testCompile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2'
    testCompile 'com.taroid.knit:knit:0.1.2'
    testCompile 'com.github.sys1yagi:kmockito:0.1.2'
    }

    View Slide

  26. KotlinͰςετΛॻ͍͍ͯ͘
    26

    View Slide

  27. 27
    Client
    Dao
    %BUBCBTF API
    Client
    Repository
    UseCase
    Presenter
    Activity / Fragment
    Service
    3FUSPpUͷ*OUFSGBDFΛར༻ͯ͠"1*௨৴
    Λߦ͏
    "1*ͷϨεϙϯεΛΞϓϦ಺Ͱར༻͠΍
    ͍͢ܗʹม׵͢Δ

    View Slide

  28. 28
    Client
    class UserClient (private val service: UserService) {


    fun fetchSearchUsers(): Observable> {

    return service.fetchSearchUsers()

    .map { response -> UserConverter.convert(response) }

    }

    }

    View Slide

  29. 29
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  30. 30
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  31. 31
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  32. 32
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  33. 33
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  34. 34
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  35. 35
    Client
    val userService = mock()

    val client = UserClient(userService)


    @Test fun testFetchSearchUsers() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    userService.getUsers().invoked.thenReturn(expected.toObservable())

    client.fetchUsers().test().run {

    assertNoErrors()

    assertValue(expected)

    assertCompleted()

    }

    }

    View Slide

  36. 36
    Dao
    Dao
    %BUBCBTF API
    Client
    Repository
    UseCase
    Presenter
    Activity / Fragment
    Service
    %BUBCBTFͷ$36%ॲཧΛߦ͏

    View Slide

  37. 37
    Dao
    class UserDao (private val orma: OrmaDatabase) {

    fun save(users: List) {

    orma.transactionSync {

    orma.prepareInsertIntoUser(OnConflict.REPLACE)

    .executeAll(users)

    }

    }


    fun findAll(): Observable> {

    return orma.selectFromUser()

    .executeAsObservable().toList()

    }

    }

    View Slide

  38. 38
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  39. 39
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  40. 40
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  41. 41
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  42. 42
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  43. 43
    Dao
    val orma = OrmaDatabase.builder(context).name(null).build()
    val dao = UserDao(orma)
    @Test fun testSave() {

    val dummyUsers = Array(10) { MockUser.newInstance(it) }

    dao.transactionSync { dummyUsers.forEach { dao.save(it) } }


    dummyUsers.forEach {

    val found = orma.selectFromUser().userRandIdEq(it.userId).get(0)

    found.rshould be it

    }

    }

    View Slide

  44. 44
    Repository
    Dao
    %BUBCBTF API
    Client
    Repository
    UseCase
    Presenter
    Activity / Fragment
    Service
    σʔλͷऔಘɾอଘΛߦ͏

    View Slide

  45. 45
    Repository
    class UserRepository (
    private val dao: UserDao,
    private val client: UserClient) {

    fun searchUsers(): Observable> {

    return client.searchUsers()
    .doOnNext { users -> dao.save(users) }
    .onErrorResumeNext { dao.findAll() }

    }

    }

    View Slide

  46. 46
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  47. 47
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  48. 48
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  49. 49
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  50. 50
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  51. 51
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  52. 52
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  53. 53
    Repository
    val dao = mock(); val client = mock()
    val repository = UserRepository(dao, client)

    fun testSearchUsers() {
    val expected = Array(10) { MockUser.newInstance(it) }.toList()
    client.fetchUsers().invoked.thenReturn(expected.toObservable())
    val subscriber = TestSubscriver()
    repository.searchUsers().subscribe(subscriber)
    with(subscriber){
    assertNoErrors()
    onNextEvents.size.should be 1
    assertCompleted()
    }
    }

    View Slide

  54. 54
    UseCase
    Dao
    %BUBCBTF API
    Client
    Repository
    UseCase
    Presenter
    Activity / Fragment
    Service
    ϏδωεϩδοΫΛදݱ͢Δ

    View Slide

  55. 55
    UseCase
    class UserUseCase (private val repository: UserRepository) {
    public Observable> searchUsers() {

    return repository.searchUsers();

    }
    public Observable> fetchRecommendLikeUsers() {

    return repository.fetchRecommendLikeUsers();

    }
    }

    View Slide

  56. 56
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  57. 57
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  58. 58
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  59. 59
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  60. 60
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  61. 61
    UseCase
    val repository = mock
    val useCase = UserUseCase(repository)
    @Test fun fetchStatus() {

    val expected = Array(10) { MockUser.newInstance(it) }.toList()

    repository.fetchUsers().invoked.thenReturn(expected.toObservable())


    useCase.searchUsers().test().run {

    assertNoErrors()

    assertValues(expected)

    assertCompleted()

    }

    }

    View Slide

  62. ·ͱΊ
    62

    View Slide

  63. 63
    ·ͱΊ
    Τ΢ϨΧ͸ώτΛͭͳ͙αʔϏεΛఏڙ͍ͯ͠Δ
    ςετ͕ແ͍ঢ়ଶ͸ࣄނ͕ى͜Γ΍͍͢ঢ়ଶͰ͋Δ
    ,PUMJOಋೖͷલʹมߋɾ௥Ճʹڧ͍ίʔυϕʔεͷํ͕ΠϯύΫτେ͖͍
    ϓϩμΫγϣϯίʔυʹ,PUMJOΛೖΕΔͷ͕ා͍࣌͸ςετίʔυ͔Βೖ
    ΕͯΈΔͱΑ͍

    View Slide

  64. Credit: NASA Earth Observatory/NOAA NGDC
    Thank you :)

    View Slide