單元測試-repo-斷言小記

記錄一下在寫repo類的單元測試時遇到的問題

測試框架使用Robolectric+Mockito
網絡框架:rxjava2+retrofit2

最初我自己寫TestRule繼承ExternalResource來幫我做一下執行repo單元測試方法之前和之後應該做的事,例如:

1.登陸取獲usertoken
2.重置數據庫,在`Robolectric`框架下不重置會出現問題

結束時

1.做斷言

爲什麼在結束時做斷言?

因爲我測試的類是repo,是專門用來與服務器做交互的部分,斷言的類型非常單一,都是在一個callback上判斷返回的數據,code=200,或者數據非空就行,本來我是這麼寫的:


var callBack: (Any) -> Unit = {result->
      if (result is Resource<*>) {
            Assert.assertThat((result as? Resource<*>)?.status,         CoreMatchers.`is`(Status.SUCCESS))
        } else {
            Assert.assertNotNull(result)
        }
}

看上去沒啥問題但是出現了關鍵問題1:

這樣寫assert不會生效

因爲assert其實是一個異常,單元測試框架捕獲到這個異常,就給你來一個測試不通過

但是這個callback回調是網路請求的,網絡請求的結構是最流行的rxjava+retrofit的那一套,這個callback方法在rxjava的方法內

而rxjava的方法是throw Throwable的,assert在callback裏是無效的,異常根本報不出來,throw了····

好吧這是來到我們的斷言2.0:

var result: Any? = null
var callBack: (Any) -> Unit = {
        result = it
    }

fun after() {
    if (result is Resource<*>) {
        Assert.assertThat((result as? Resource<*>)?.status, CoreMatchers.`is`(Status.SUCCESS))
    } else {
        Assert.assertNotNull(result)
    }
}

這個after()方法就是ExternalResource的方法,會在每個單元測試的方法執行完執行,這樣總行了吧

我跑了一下單元測試大多數都正常了,但是還是出現了一個小問題,我在單獨運行一個單元測試方法時一切都是正常的,然後運行一整個單元測試類的時候,斷言的錯誤不會出現在單元測試方法內,而是出現在了after()方法裏,這讓我找問題很不好找我以爲測試方法裏的斷言是都過了的···其實沒有···害我找我半天問題····

那爲什麼會這樣的?

答案在下面這段代碼裏,它來自我們的ExternalResource

 private Statement statement(final Statement base) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                before();
                try {
                    base.evaluate();
                } finally {
                    after();
                }
            }
        };
    }

沒錯ExternalResourcetry包裹了我們的測試方法,我不知道爲啥···我有點委屈····

但是好在問題找到了,找到了就好解決了,我複製了ExternalResource裏面的全部代碼去掉了try然後讓我的RepoTestRule直接實現TestRule暫時沒發現問題···如果出現新的問題我會及時更新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章