kitlangton / stubby   0.1.2

GitHub

A simple stubbing library for ZIO tests.

Scala versions: 3.x

stubby

Release Artifacts Snapshot Artifacts

A simple stubbing library for ZIO tests.

libraryDependencies += "io.github.kitlangton" %% "stubby" % "0.1.2"

Example Usage

Given the following contrived API.

trait MagicAPI:
  def destroyPlanet(planet: String): IO[MagicError, Unit]
  def pureMethod(int: Int): String

enum MagicError extends Exception:
  case MagicBackfired
  case TooManyMagic

And the following application logic.

class App(magicApi: MagicAPI):
  def destroy: Task[String] =
    magicApi
      .destroyPlanet("Earth")
      .as("Planet destroyed")
      .catchAll {
        case MagicError.MagicBackfired => ZIO.succeed("Magic backfired")
        case MagicError.TooManyMagic   => ZIO.succeed("Too many magic")
      }

  def usePure: String =
    s"Pure Magic: ${magicApi.pureMethod(42)}"

object App:
  val layer: ZLayer[MagicAPI, Nothing, App] =
    ZLayer.fromFunction(App.apply)

  def destroy = ZIO.serviceWithZIO[App](_.destroy)
  def usePure = ZIO.serviceWith[App](_.usePure)

Use stubby to stub methods and test your application:

import zio.test.*
import zio.*
import stubby.*

object AppSpec extends ZIOSpecDefault:
  val spec =
    suiteAll("App") {

      test("fails when magic backfires") {
        for
          // Override the destroyPlanet method to always fail with MagicBackfired
          _ <- stub[MagicAPI](_.destroyPlanet(any)) {
                  ZIO.fail(MagicError.MagicBackfired)
                }
          result <- App.destroy
        yield assertTrue(result == "Magic backfired")
      }

      test("returns the result of the pure method") {
        for
          // Or stub a pure method to return a specific value
          _ <- stub[MagicAPI](_.pureMethod(any)) {
                  "HELP ME I'M TRAPPED IN AN EXAMPLE"
                }
          result <- App.usePure
        yield assertTrue(result == "Pure Magic: HELP ME I'M TRAPPED IN AN EXAMPLE")
      }

    }.provide(
      App.layer,
      stubbed[MagicAPI] // <- stubbed[MagicAPI] will create a Layer[MagicAPI]
    )