2017-08-02 120 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))) 
} 

请注意,每次调用存根方法时都会创建一个新的模拟对象。在某些情况下,如果您想对内部模拟执行验证,可能并不理想。