LoginSignup
7
6

More than 5 years have passed since last update.

Mockito-Kotlinの使用例

Last updated at Posted at 2018-11-14

AndroidプロジェクトでKotlin Mockitを使うメモ

参考資料

Mocking and verifying · nhaarman/mockito-kotlin Wiki
Kotlin with Mockito | Baeldung

build.gradle

以下の依存を追加する

build.gradle
dependencies {
...
    testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-RC1'
    testImplementation 'org.mockito:mockito-android:2.22.0'
...

Mock

モックとは

​mockメソッドを使うと、そのクラスの実装に依存しないモックオブジェクトを生成します。
各メソッドの戻り値はモックオブジェクトになりますが、指定したメソッドの戻り値だけを任意に設定できます。
Mockito 初めの一歩

実行結果を上書きする

関数test1()の実行結果を上書きする

テストコード
    @Test
    fun test1(){
        val testClass = mock<MyTestClass> {
            on{testFunction()} doReturn "mock response"
        }
        assertEquals("mock response",testClass.testFunction())
    }

    class MyTestClass{
        fun testFunction():String{
            return "testCalling inside"
        }
    }

実行結果を上書きする(呼び出しごとに変化する)

関数test1()の実行結果を上書きするが、呼び出しごとに順番に返却する値を変える。

テストコード
    @Test
    fun testList(){
        val testClass = mock<TestClass> {
            on{test()} doReturn listOf<String>("1","2","3")
        }
        assertEquals("1",testClass.test())
        assertEquals("2",testClass.test())
        assertEquals("3",testClass.test())
    }

    class MyTestClass{
        fun testFunction():String{
            return "testCalling inside"
        }
    }

コールバックインターフェースが呼ばれたか確認する

インターフェースTestInterfaceをモック、TestClassにそのモックインターフェースを渡す。
そのときインターフェースのonUpdateが呼ばれていることを確認する。

テストコード
    @Test
    fun test(){
        val testIf : TestInterface = mock()
        val testClass = TestClass(testIf)
        testClass.test()
        verify(testIf).onUpdate("mocked update") // TestInterface.onUpdateに("haha")が渡された状態になっているか
    }

    interface TestInterface{
        fun onUpdate(str:String)
    }

    class TestClass(val myIf:TestInterface){
        fun test():String{
            myIf.onUpdate("mocked update") // onUpdate実行、"mocked update"返却。
            return "this is test."
        }
    }

コールバックインターフェースの実行結果を上書きする

テストコード
    @Test
    fun test5(){

        val TEST_STRING = "Can I Create?"
        val EXPECTED_RESULT = "Success"

        val testIf : TestInterface = mock()
        whenever(testIf.create(TEST_STRING)).thenReturn(EXPECTED_RESULT) // インターフェースにTEST_STRINGが渡されたとき、EXPECTED_RESULTを返却するモックを作成

        val testClass = TestClass(testIf)
        val result = testClass.testCreate(TEST_STRING)
        verify(testIf).create(TEST_STRING) // インターフェースが、渡した値で呼ばれているか
        assertEquals(EXPECTED_RESULT, result) // testCreate()の返り値を確認。 ( ≒ whenever節で設定した値でインターフェースが返却されたか )

    }

    interface TestInterface{
        fun create(str:String):String
    }

    class TestClass(val myIf:TestInterface){
        fun testCreate(str: String):String{
            return myIf.create(str)
        }
    }

Spy

一部のメソッドの実行結果のみを上書きし、それ以外はもともとの実装を利用する。

spyメソッドを使うと、任意のインスタンスの一部だけモックできます。
spyで得たオブジェクトは、モックしたメソッドの他は元々の実装で動作します。
Mockito 初めの一歩

テスト対象コードとテストコード
    @Test
    fun spy1(){
        val spiedClass = spy(XP1DataTransportClientService.TestClass2())
        spiedClass.testCall()
        verify(spiedClass).testCall2()
    }
    class TestClass2(){
        fun testCall(){
            testCall2()
        }
        fun testCall2(){

        }
    }
テスト対象コードとテストコード
    @Test
    fun passAnyStringToSpy() {
        /* Given */
        val my = spy(MyClass())

        /* When */
        doReturn("mocked").whenever(my).foo(any())

        /* Then */
        expect(my.foo("hello")).toBe("mocked")
    }

    private interface MyInterface {

        fun foo(value: String): String
    }

    private open class MyClass : MyInterface {

        override fun foo(value: String): String = value
    }

いまさら聞けなかったこと

  • Mockitoが使えるのはUnit Testのみ。Instrumentation Testは不可。
  • Log.d(...)ではUnit Testではログは出力されない(あたりまえか)。printlnで。
7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6