101010

プログラミング備忘録とともに、ポエムってます。

Mockitoを使ったはじめてのテスト | Android Kotlin

Mockitoの使い方を学ぶために行ったサンプルテストを記述していく。

Mockitoを使えるようにGradleでインストール

testImplementation 'org.mockito:mockito-core:2.21.0'

簡単なプログラムでテストする

まずはMockitoを動かしてみるため簡単なハローワールドテストプログラムを作成する。

class Hoge {
    fun display(message:String) {
        println(message)
    }
}

@Test
fun Mockitoのはじめのてすと() {

    val hoge  = mock(Hoge::class.java)
    hoge.display("hello")

    verify(hoge).display("hello")
}

なるほど、verify(hoge).display("hello")というのはhogeインスタンスのdisplay("hello")が呼ばれたかどうかを確認しているというこいとか。

whenとthenReturnを理解する

class Fuga {
    fun saySomething():String {
        return "hi!"
    }
}

@Test
fun WhenとThenを理解する() {
    val fuga  = mock(Fuga::class.java)
    val mockValue = "wow!"

    `when`(fuga.saySomething()).thenReturn(mockValue)

    assert(fuga.saySomething() == mockValue)
//        assert(fuga.saySomething() == "hi!") // これは通らない
}

この動作確認でだんだんMockの意味がわかってきた!FugaクラスのsaySomethinghi!を定義したはずだが、mockを使うことで戻り値を変更することが出来るのだ!上記の例ではwow!を返すようにwhenthenReturnを使って定義している。

whenとthenReturnを理解する2

先の例のFugaクラスを少し変えて次のように定義した。

class Fuga {
    fun saySomething(index:Int):String {
        return when(index) {
            0 -> "hi!"
            1 -> "Hello!"
            2 -> "Yah!"
            else -> ""
        }

    }
}

mockを使って次のようにテストしてみるとどうだろうか?

@Test
fun WhenとThenを理解する2() {
    val fuga  = mock(Fuga::class.java)
    val mockValue = "wow!"

    `when`(fuga.saySomething(0)).thenReturn(mockValue)

    assert(fuga.saySomething(0) == mockValue) { fuga.saySomething(0) }
    assert(fuga.saySomething(1) == "Hello!") { fuga.saySomething(1) } // これは通らない!
}

fuga.saySomething(0)はwhen thenReturnを使ってwow!に書き換えられているので前回のテストと同様に成功する。 しかしfuga.saySomething(1)Hello!が返ってくると思いきやnullとなってテストは通らないのだ。つまり定義されていないということになっている。これでは不便なときもあるだろう。Fugaの定義を使って一部だけメソッドを書き換えたい場合はどうすれ良いだろうか?それには次のspyを使うと良いようだ。

spyを理解する

先程定義したFugaクラスをそのまま使いspyを使って同じようにテストをしてみる。

@Test
fun spyを理解する() {
    val fuga  = spy(Fuga())
    val mockValue = "wow!"

    `when`(fuga.saySomething(0)).thenReturn(mockValue)

    assert(fuga.saySomething(0) == mockValue) { fuga.saySomething(0) }
    assert(fuga.saySomething(1) == "Hello!") { fuga.saySomething(1) }
    assert(fuga.saySomething(2) == "Yah!") { fuga.saySomething(2) }
    assert(fuga.saySomething(3) == "") { fuga.saySomething(3) }
}

今度はテスト結果がグリーンとなって成功した!

verifyでメソッドが何回呼ばれたか確認する

@Test
fun verifyでメソッドが何回呼ばれたか確認する() {
    val fuga  = spy(Fuga())

    fuga.saySomething(0)
    fuga.saySomething(0)
    fuga.saySomething(0)


    fuga.saySomething(1)
    fuga.saySomething(1)

    verify(fuga, times(3)).saySomething(0)
    verify(fuga, times(2)).saySomething(1)
}