<th id="uz6zr"><table id="uz6zr"><sub id="uz6zr"></sub></table></th> <tbody id="uz6zr"></tbody>
  • <menuitem id="uz6zr"><dfn id="uz6zr"></dfn></menuitem><menuitem id="uz6zr"><strong id="uz6zr"></strong></menuitem>
      1. Kotlin 測試利器—MockK

        發表于:2020-10-13 09:31  作者:嘻嘻z   來源:掘金

        字體: | 上一篇 | 下一篇 |我要投稿 | 推薦標簽: 測試工具

          為什么需要MockK
          在MockK之前,已經有一大批測試庫可以用于Mocking,其中有名的也有很多,比如Mockito, PowerMock,Jmockit等等,但是他們都有各自的缺陷,這些缺陷也和Kotlin的特性有關。
          關鍵字
          在 Kotlin 裡面 when是關鍵字,Mockito 的when ,必須加上反引號才能使用:
        `when`(xxxx).thenReturn(xxx)
          如果看起來不舒服,也可以舍棄 Mockito 改用 mockito-kotlin。
          在 mockito-kotlin中使用了whenever代替when,也有更簡潔的寫法,但是歸根到底還是在使用Mockito的Api,所以功能上依然有局限性。
          Mock Kotlin的類時報錯
        org.mockito.exceptions.base.MockitoException: 
        Cannot mock/spy class com.joetsai.kotlinunittest.token.TokenRepository
        Mockito cannot mock/spy because :
         — final class
          這是因為Kotlin中類都是默認final類型,如果需要mock,則需要顯示的加上open標識符,如果有100個類,則需要加100次,這也太麻煩了…
          靜態方法如何Mock
          眾所周知,Mockito是不支持靜態方法的,如果想使用就需要使用PowerMock,但是PowerMock也有缺點。
          使用流程也比較繁瑣
          Mockito與PowerMock是不同團隊開發的,更新速度慢而且有兼容性問題。
          Jmockit
          完全與kotlin不兼容…
          MockK使用示例
          普通使用
        fun test() {
            val mother = mockk<Mother>()
            every { mother.giveMoney() } returns 30 // when().thenReturn() in Mockito
            assertEquals(30, mother.giveMoney())
        }
          mockkObject
        object Son {
            fun test5(): Int {
                return 5
            }
        }

        mockkObject(Son)
        every { Son.test5() } returns 10
        assertEquals(10, Son.test5())
          mockkStatic
        class Son {
            Static int test5() {
                return 5
            }
        }   
        @test
        fun test() {
            mockkStatic(Son::class)
            every { Son.test5() } returns 10
            assertEquals(10, Son.test5())
        }
          mock private method
        class Son {
            public int publicResult() {
                return privateResult()
            }

            private int privateReuslt() {
                return 5
            }
        }   
        @test
        fun test() {
            val son = mockk<Son>()
            every { son["privateResult"]() } returns 10
            assertEquals(10, son.publicResult())
        }
          Context Mock
          在某些Android某些用戶自定義的類中,需要Context才能初始化。
        class Utils {
            public static void initialize(Context context) {
            instance = builder.build(context);
            }
            public static synchronized Utils getInstance() {
                if (instance == null) {
                    throw new IllegalStateException("you must call initialize first");
                }
                return instance;
            }
        }
          有兩種初始化方式:
          直接mock context
        val context = mockk<Context>()
        Utils.init(context)
        Utils.getInstance().xxxx()
          直接mock Util
        val mockApplicationContext = mockk<Context>()
        val utils = mockk<Utils.init>()
        mockkStatic(Utils.init::class)
        every { Utils.getInstance() } returns utils
        every { utils.test() } returns null
        ......
          遇到的一些小坑
          從介紹來看,在mockStatic時只能mock非final類,所以如果mock系統自帶的System類會直接報錯。
          在Android instrument test時,需要設備Android版本>=9。
          在最新版(1.10.2)的MockK中,需要kotlin版本>=1.3.61
          最后
          因為當前項目是java和kotlin混編的,所以舉得例子中也有不少java的demo。
          如果大家還有其他遇到的問題或者坑,歡迎留言。

          本文內容不用于商業目的,如涉及知識產權問題,請權利人聯系51Testing小編(021-64471599-8017),我們將立即處理

        評 論

        論壇新帖

        頂部 底部


        建議使用IE 6.0以上瀏覽器,800×600以上分辨率,法律顧問:上海瀛東律師事務所 張楠律師
        版權所有 上海博為峰軟件技術股份有限公司 Copyright©51testing.com 2003-2020, 滬ICP備05003035號
        投訴及意見反饋:webmaster@51testing.com; 業務聯系:service@51testing.com 021-64471599-8017

        滬公網安備 31010102002173號

        51Testing官方微信

        51Testing官方微博

        掃一掃 測試知識全知道

        在线看黄AV免费悠久