I'm starting unit testing in scala using scalatest. the method I'm testing is as follows :
def readAlpha: IO[Float] = IO {
val alpha = scala.io.StdIn.readFloat()
alpha
}
The test consists of limiting the float that the user inserts to two decimals Here is what I've tried but that doesn't seem to work. How could I be fixing it
"alpha" should " have two decimal numbers after comma" in {
val alpha = readAlpha
//assert(alpha == (f"$alpha%.2f"))
}
I cannot say that you are doing wrong, but you cannot compare effect type with a pure type. And It's not possible to write a direct test for the console input app. First of you should mock the readAlpha
method somehow, then you should evaluate the value and after that, it's possible to compare them. Here is a small demonstration:
import cats.effect.IO
class ConsoleIO {
def readAlpha: IO[Float] = IO {
val alpha = scala.io.StdIn.readFloat()
alpha
}
}
// ---------------------------------
import cats.effect.{ContextShift, IO, Timer}
import org.scalatest.funsuite.AsyncFunSuite
import scala.concurrent.ExecutionContext
class ConsoleIOTest extends AsyncFunSuite {
class MockConsole extends ConsoleIO {
override def readAlpha: IO[Float] = IO.pure(2.23f)
}
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global)
test("alpha should have two decimal numbers after comma") {
val consoleIO = new MockConsole
val alpha = consoleIO.readAlpha.unsafeRunSync()
assert(alpha.toString === (f"$alpha%.2f"))
}
}
Here unsafeRunSync()
produces the result by running the encapsulated effects as impure.