scalamock logo


Native Scala mocking framework

Introduction Getting started View on GitHub


Supported Platforms

Scala Version JVM JS (1.x) Native (0.5.x)
2.12.x Coming soon
2.13.x Coming soon
3.x Coming soon

Dependencies

sbt

libraryDependencies ++= Seq(
  // core module
  "org.scalamock" %% "scalamock" % "<version in the badge>" % Test,
  // zio integration
  "org.scalamock" %% "scalamock-zio" % "<version in the badge>" % Test,
  // cats-effect integration
  "org.scalamock" %% "scalamock-cats-effect" % "<version in the badge>" % Test
)

Mill

object main extends JavaModule {
  object test extends JavaModuleTests {
    override def ivyDeps =
      Agg(
        ivy"org.scalamock::scalamock:<version in the badge>",
        // zio integration
        ivy"org.scalamock::scalamock-zio:<version in the badge>",
        // cats-effect integration
        ivy"org.scalamock::scalamock-cats-effect:<version in the badge>"
      )
  }
}

Scala-CLI

//> using test.dep "org.scalamock::scalamock:<version in the badge>"
//> using test.dep "org.scalamock::scalamock-zio:<version in the badge>"
//> using test.dep "org.scalamock::scalamock-cats-effect:<version in the badge>"

Maven

<dependencies>
  <!-- core module -->
  <dependency>
    <groupId>org.scalamock</groupId>
    <artifactId>scalamock_3</artifactId>
    <version><!-- version in the badge --></version>
    <scope>test</scope>
  </dependency>
  <!-- zio integration -->
  <dependency>
    <groupId>org.scalamock</groupId>
    <artifactId>scalamock-zio_3</artifactId>
    <version><!-- version in the badge --></version>
    <scope>test</scope>
  </dependency>
  <!-- cats-effect integration -->
  <dependency>
    <groupId>org.scalamock</groupId>
    <artifactId>scalamock-cats-effect_3</artifactId>
    <version><!-- version in the badge --></version>
    <scope>test</scope>
  </dependency>
</dependencies>

Getting started

Classic + scalatest

//> using test.dep org.scalamock::scalamock:7.3.2
//> using test.dep org.scalatest::scalatest:3.2.19

import org.scalamock.scalatest.MockFactory
import org.scalatest.flatspec.AnyFlatSpec

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MyTest extends AnyFlatSpec, MockFactory:
  trait Wiring:
    val service1 = stub[Service1]
    val service2 = mock[Service2]
    val service3 = Service3(service1, service2)

  it should "do something" in new Wiring {
    // service1.someMethod.when(...).returns(...)
    // service2.someMethod.expects(...).returns(...)
    // run tested method
    // service1.someMethod.verify(...).once()
  }

Classic + specs2

//> using test.dep org.scalamock::scalamock:7.3.2
//> using test.dep org.specs2::specs2-core:5.6.3

import org.scalamock.specs2.MockContext
import org.specs2.mutable.Specification

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MySpec extends Specification {

  trait Wiring extends MockContext {
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)
  }
  
  "CoffeeMachine" should {
    "not turn on the heater when the water container is empty" in new Wiring {
      // service1.someMethod.when(...).returns(...)
      // service2.someMethod.expects(...).returns(...)
      // run tested method
      // service1.someMethod.verify(...).once()
    }
  }
}

Stubs + munit

//> using test.dep org.scalamock::scalamock:7.3.2
//> using test.dep org.scalameta::munit:1.1.1

import org.scalamock.stubs.Stubs
import munit.FunSuite

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MyTest extends FunSuite, Stubs:
  class Env:
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)


  test("do something"):
    val env = Env()
    // env.service1.someMethod.returnsWith(...)
    // env.service2.someMethod.returnsWith(...)
    // run tested method
    // assertEquals(env.service1.calls, List(...))
    // assertEquals(env.service2.times, ...)

Stubs + scalatest

//> using test.dep org.scalamock::scalamock:7.3.2
//> using test.dep org.scalatest::scalatest:3.2.19

import org.scalamock.stubs.Stubs
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MyTest extends AnyFunSuite, Matchers, Stubs:
  class Env:
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)

  test("do something"):
    val env = Env()
    // env.service1.someMethod.returnsWith(...)
    // env.service2.someMethod.returnsWith(...)
    // run tested method
    // env.service1.calls shouldBe List(...)
    // env.service2.times shouldBe ...

Stubs + specs2

//> using test.dep org.scalamock::scalamock:7.3.2
//> using test.dep org.specs2::specs2-core:5.6.3

import org.scalamock.stubs.Stubs
import org.specs2.mutable.Specification

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MySpec extends Specification, Stubs:
  class Env:
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)

  "do something" should {
    "work" in {
      val env = Env()
      // env.service1.someMethod.returnsWith(...)
      // env.service2.someMethod.returnsWith(...)
      // run tested method
      // env.service1.calls check
      // env.service2.times check
    }
  }

Stubs + ZIO test

//> using dep dev.zio::zio:2.1.17
//> using test.dep dev.zio::zio-test:2.1.17
//> using test.dep org.scalamock::scalamock-zio:7.3.2

import org.scalamock.stubs.ZIOStubs
import zio.test.*

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MyTest extends ZIOSpecDefault, ZIOStubs:
  class Env:
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)

  override def spec: Spec[TestEnvironment & Scope, Any] =
    suite("tests")(
      test("do something") {
        val env = Env()
        /*
            for {
              _ <- env.service1.someMethod.succeedsWith(...)
              _ <- env.service2.someMethod.succeedsWith(...)
              result <- env.service3 logic to test
            yield assertTrue(
              result == ...,
              env.service1.someMethod.calls == ...,
              env.service2.someMethod.times == ...
            )
         */
      }
    )

Stubs + munit-cats-effect

//> using dep org.typelevel::cats-effect:3.6.1
//> using test.dep org.scalamock::scalamock-cats-effect:7.3.2
//> using test.dep org.typelevel::munit-cats-effect:2.1.0

import org.scalamock.stubs.CatsEffectStubs
import cats.effect.*
import munit.*

trait Service1
trait Service2
class Service3(service1: Service1, service2: Service2)

class MyTest extends CatsEffectSuite, CatsEffectStubs:
  class Env:
    val service1 = stub[Service1]
    val service2 = stub[Service2]
    val service3 = Service3(service1, service2)

  test("do something"):
    val env = Env()
    /*
        for {
          _ <- env.service1.someMethod.succeedsWith(...)
          _ <- env.service2.someMethod.succeedsWith(...)
          result <- env.service3 logic to test
        } yield {
          assertEquals(result, ...)
          assertEquals(env.service1.someMethod.calls, ...)
          assertEquals(env.service2.someMethod.times, ...)
        }
     */