I'm having trouble mocking the MVar2
method make
in my Unit test (using mockito).
I tried this:
private val sq = mock[MVar2[IO, String]]
and when I tried to mock the method like:
when(sq.take).thenReturn(
"testString".pure[IO],
IO.never
)
I get the infinite loop in the test.
I was positive I could mock it like this.
The actual code calling the make
is:
def run: F[Unit] =
fs2.Stream
.repeatEval[F, String](signalQ.take)
.map(encode)
.unNone
.evalTap(logMessage)
.evalMap(send)
.compile
.drain
CodePudding user response:
I see two issues.
The first thing, there is no reason to mock IO. You can pretty much do this:
// define this wherever you create sq
val sq = MVar2[IO, String]
// then DI sq and
sq.put("testString") >> run
Then the second thing, how does .repeatEval(io)
works? It calls io
repeatedly, every time the stream needs another element. So at first it would evaluate io
with your mock to:
"testString".pure[IO]
which would compute the first element to "testString"
and later to
IO.never
which means that the second element would never appear as this io
would never return - neither value nor exception. And your stream halts as you can see. (Which would be according to the spec but apparently not what you want).
If you wanted to get Some(string)
if value is present and None
if it's absent (to terminate stream on None
) you should try:
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