Модульное тестирование IO Scala - PullRequest
0 голосов
/ 16 апреля 2020

Я начинаю юнит-тестирование в scala, используя скалестат. метод, который я тестирую, выглядит следующим образом:

 def readAlpha: IO[Float] = IO {
    val alpha = scala.io.StdIn.readFloat()
    alpha
  }

Тест состоит в ограничении числа с плавающей точкой, которое пользователь вставляет двумя десятичными знаками. Вот то, что я пробовал, но, похоже, это не работает. Как я мог это исправить

  "alpha" should " have two decimal numbers after comma" in {
    val alpha = readAlpha
    //assert(alpha == (f"$alpha%.2f"))
  }

1 Ответ

1 голос
/ 16 апреля 2020

Я не могу сказать, что вы делаете неправильно, но вы не можете сравнить тип эффекта с чистым типом. И невозможно написать прямой тест для приложения ввода с консоли. Сначала вы должны каким-то образом смоделировать метод readAlpha, затем вы должны оценить значение и после этого можно сравнить их. Вот небольшая демонстрация:

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"))
  }

}

Здесь unsafeRunSync() дает результат, запуская инкапсулированные эффекты как нечистые.

...