0

我有一个问题。我将以下函数与 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 循环。有人可以帮忙吗?谢谢

4

1 回答 1

1

为什么你需要嘲笑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 类都这么说)。

因此,模拟 IO、Resource、Ref 与模拟案例类或一般的 List/Option/Vector/Set/containers 一样没有意义。如果你将函数作为参数传递也是一样的——如果你可以传递实现,为什么还要模拟?资源只是一对acquirerelease函数。您可以比 mockito 模拟它们更快地实现它们。

于 2020-05-16T17:34:35.060 回答