简体   繁体   中英

Unit Testing IO Scala

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM