如何模拟 MVar2 make 方法
How to mock MVar2 make method
我在单元测试(使用 mockito)中模拟 MVar2
方法 make
时遇到问题。
我试过这个:
private val sq = mock[MVar2[IO, String]]
当我尝试像这样模拟方法时:
when(sq.take).thenReturn(
"testString".pure[IO],
IO.never
)
我在测试中得到了无限循环。
我很确定我可以像这样嘲笑它。
调用make
的实际代码是:
def run: F[Unit] =
fs2.Stream
.repeatEval[F, String](signalQ.take)
.map(encode)
.unNone
.evalTap(logMessage)
.evalMap(send)
.compile
.drain
我看到两个问题。
首先,没有理由模拟 IO。你几乎可以做到这一点:
// define this wherever you create sq
val sq = MVar2[IO, String]
// then DI sq and
sq.put("testString") >> run
那么第二件事,.repeatEval(io)
是如何工作的?每次流需要另一个元素时,它都会重复调用 io
。所以起初它会用你的模拟评估 io
到:
"testString".pure[IO]
这会将第一个元素计算为 "testString"
,然后计算为
IO.never
这意味着第二个元素永远不会出现,因为这个 io
永远不会 return - 既不是值也不是异常。如您所见,您的流停止了。 (这将符合规范,但显然不是您想要的)。
如果你想在值存在时获取 Some(string)
,在值不存在时获取 None
(在 None
上终止流)你应该尝试:
def run: F[Unit] =
fs2.Stream
.repeatEval[F, Option[String]](signalQ.tryTake)// <-- try to get None on empty
.unNoneTerminate // <-- terminate on None
.map(encode)
.evalTap(logMessage)
.evalMap(send)
.compile
.drain
我在单元测试(使用 mockito)中模拟 MVar2
方法 make
时遇到问题。
我试过这个:
private val sq = mock[MVar2[IO, String]]
当我尝试像这样模拟方法时:
when(sq.take).thenReturn(
"testString".pure[IO],
IO.never
)
我在测试中得到了无限循环。
我很确定我可以像这样嘲笑它。
调用make
的实际代码是:
def run: F[Unit] =
fs2.Stream
.repeatEval[F, String](signalQ.take)
.map(encode)
.unNone
.evalTap(logMessage)
.evalMap(send)
.compile
.drain
我看到两个问题。
首先,没有理由模拟 IO。你几乎可以做到这一点:
// define this wherever you create sq
val sq = MVar2[IO, String]
// then DI sq and
sq.put("testString") >> run
那么第二件事,.repeatEval(io)
是如何工作的?每次流需要另一个元素时,它都会重复调用 io
。所以起初它会用你的模拟评估 io
到:
"testString".pure[IO]
这会将第一个元素计算为 "testString"
,然后计算为
IO.never
这意味着第二个元素永远不会出现,因为这个 io
永远不会 return - 既不是值也不是异常。如您所见,您的流停止了。 (这将符合规范,但显然不是您想要的)。
如果你想在值存在时获取 Some(string)
,在值不存在时获取 None
(在 None
上终止流)你应该尝试:
def run: F[Unit] =
fs2.Stream
.repeatEval[F, Option[String]](signalQ.tryTake)// <-- try to get None on empty
.unNoneTerminate // <-- terminate on None
.map(encode)
.evalTap(logMessage)
.evalMap(send)
.compile
.drain