2017-08-02 119 views
0

我得到的錯誤是org.mockito.exceptions.misusing.UnfinishedStubbingException,其中一個可能的原因是「如果完成之前你在另一個模擬內部存儲行爲」。模擬創作內Mockito模擬創建

val mockHttpHandlerContext = mock<HttpHandlerContext>().let { 
     whenever(it.request).thenReturn(mock<HttpRequest>().let { 
      whenever(it.queryParameters).thenReturn(mapOf(
        "itype" to listOf("msisdn"), 
        "uid" to listOf(inputMsisdn) 
      )) 
      it 
     }) 
     whenever(it.scope()).thenReturn(ProcessingScope.of(Timings("test", 1000L))) 
     it 
    } 

是擺脫嵌套模擬創造的唯一解決方案?這真的會讓代碼更難理解,也許有一個已知的解決方法?

代碼片段是Kotlin。

回答

1

通過命名判斷,我假設您使用的是nhaarman/Mockito-Kotlin

Mockito是有狀態的,您必須依次創建mock,但有一些方法可以翻轉評估順序。例如,

val mockHttpHandlerContext2 = mock<HttpHandlerContext>() { 
    mock<HttpRequest>() { 
     on { queryParameters }.thenReturn(mapOf(
       "itype" to listOf("msisdn"), 
       "uid" to listOf(inputMsisdn) 
     )) 
    }.let { on { request }.thenReturn(it) } 
    on { scope() }.thenReturn(ProcessingScope.of(Timings("test", 1000L))) 
} 

我趁着mock()超載與KStubbing<T>接收器的,但重要的一點是使用.let來設置它的存根之前先建​​立內部模擬。

另一種選擇是使用​​推遲內部模擬的創建,直到調用存根方法的時間。

val mockHttpHandlerContext = mock<HttpHandlerContext>() { 
    on { request }.thenAnswer { 
     mock<HttpRequest>() { 
      on { queryParameters }.thenReturn(mapOf(
        "itype" to listOf("msisdn"), 
        "uid" to listOf(inputMsisdn) 
      )) 
     } 
    } 
    on { scope() }.thenReturn((ProcessingScope.of(Timings("test", 1000L))) 
} 

請注意,每次調用存根方法時都會創建一個新的模擬對象。在某些情況下,如果您想對內部模擬執行驗證,可能並不理想。