kotlin 使用mockk一次仅模拟一个呼叫

u3r8eeie  于 2023-01-09  发布在  Kotlin
关注(0)|答案(4)|浏览(190)

我知道为了模拟一个方法的响应方式,必须使用

every { instanceX.methodB() } returns "42"

我试着模拟一个迭代器,你必须模拟两个方法hasNext()和next(),如果hasNext()返回真,总是会有一个无限循环,如果它从一开始就返回假,next()不会返回任何东西。
我的问题是:有没有办法用mockk一个接一个地模拟单独的调用,就像你在mockito中可以做的那样?我在文档中找不到任何东西。

uhry853o

uhry853o1#

Mocking is not rocket science后,记录了两种替代方案:
returnsMany指定一个接一个使用的值的数量,即第一个匹配的调用返回第一个元素,第二个 返回 第二个元素:

every { mock1.call(5) } returnsMany listOf(1, 2, 3)

使用andThen构造可以实现相同的效果:

every { mock1.call(5) } returns 1 andThen 2 andThen 3
xu3bshqb

xu3bshqb2#

使用带/的returnsManyandThen构造代替return

dgsult0t

dgsult0t3#

现在我有一个类似的用例,但对我来说answers是合适的解决方案,因为我已经有了一个Iterator(返回的迭代器实际上是Iterator的自定义扩展):

every { mock.bogusIterator() /* : CustomIterator */ } answers { 
  val testIterator = testList.iterator() // just an Iterator
  every { hasNext() } answers { testIterator.hasNext() }
  every { next() } answers { testIterator.next() }
}

其中testList包含用于测试的一些预定义值。
returns总是返回在那个时候给函数的值,所以使用every { hasNext() } returns whatever总是返回在那个模拟声明的时候whatever的值,不管whatever是否可变。使用answer,你总是得到你在调用函数时返回的当前值,以防有人对此感到困惑;- )也许我的进一步解释也有点混乱:-)

zqry0prt

zqry0prt4#

我无法回答@GACy20,所以我把他问题的答案放在这里。
疑问:如果我想让第一个调用抛出异常,第二个调用返回值,那么这是如何应用的呢?
你只需要这样做:

every { thing.save(any()) } throws RuntimeException("Erro") andThen aRealValue

相关问题