【问题标题】:mocking only one call at a time with mockk用 mockk 一次只模拟一个电话
【发布时间】:2019-02-18 20:53:18
【问题描述】:

我知道为了模拟一个方法如何响应,你必须使用

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

我正在尝试模拟一个迭代器,为此你必须模拟 2 个方法 hasNext() 和 next(),如果 hasNext() 返回 true 总是会有一个无限循环,如果它从一开始就返回 false, next() 不会返回任何内容。

我的问题是:有没有办法用 mocki 一个一个地模拟单个调用,就像你可以在 mockito 中那样?我在文档中找不到任何内容。

【问题讨论】:

  • 我正在使用返回 ResultSet 的库从 cassandra 获取数据,我需要测试使用该数据的服务,并模拟此 ResultSet。

标签: unit-testing kotlin mockk


【解决方案1】:

在出色的帖子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

【讨论】:

    【解决方案2】:

    returnsManyandThenreturn 一起使用/代替return

    【讨论】:

      【解决方案3】:

      现在我有一个类似的用例,但对我来说,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 总是返回当时给函数的值。因此,无论whatever 是否可变,使用every { hasNext() } returns whatever 将始终在该模拟声明时间返回whatever 的值。另一方面,使用answer,您始终可以获得调用函数时返回的当前值。万一有人对此感到困惑;-)也许我的进一步解释也有点令人困惑:-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 2013-11-30
        • 1970-01-01
        相关资源
        最近更新 更多