测试高阶函数 scala + Cats Resource

Testing Higher order functions scala + Cats Resource

我有一个问题。我将以下函数与 Scala 猫库一起使用。

 def process(
      client: Resource[IO, HttpClient] = HttpClientFactory.createClient()
  ): IO[Long] =
    client.use(httpClient => {
      for {
        files <- IO { getFiles() }
        placeMarkers <- IO { sendFile(client) }
      } yield placeMarkers
    })

现在我想用单元测试来测试这段代码,我想模拟 httpClient。 我正在尝试这样的事情,但它不起作用:

val resourceIOMock = mock[Resource[IO, HttpClient]]
val httpMock = mock[HttpClient]

doReturn(httpMock).when(resourceIOMock).use(any())

由于 Mathcers any(),这不起作用。我真的不知道如何将我的模拟传递到那里,然后可以根据需要进行配置。据我所见,代码永远不会进入 for 循环。 有人可以帮忙吗? 感谢

为什么你需要模拟 Resource?你几乎可以做类似的事情:

// given
val client = mock[HttpClient]
val clientResource = Resource.make[IO, HttpClient](IO.pure(client))(_ => IO.unit)
doReturn(client).when(methodUsedInTest).use(...)

// when
val result = process(clientResource).runSync

// then
assert(...)

如果您使用 IO 构建纯值,当您拥有非常好的工厂方法时,对它们使用模拟是没有意义的,尤其是因为 IO 是数据 - 当您创建这些值时它们不会产生副作用,只有当你解释它时(你不能说每个随机 Java class)。

因此,模拟 IO、Resource、Ref 与模拟 case classes 或 List/Option/Vector/Set/containers 一样毫无意义。如果您将函数作为参数传递,则相同 - 如果您可以传递实现,为什么还要模拟?资源只是一对 acquirerelease 函数。您可以比 mockito 模拟它们更快地实现它们。