Create many mocks quickly with annotations #

Sometimes you will need to create many mocks in your test class. As each mock needs to be declared as a property in the test class, then initialized in the test setup function, the amount of code needed to build all your mocks can grow very quickly. MockK provides a shorthand using annotations to make this simpler.

class RepositoryTest {

  @MockK private lateinit var foodDatabase: FoodDatabase
  @MockK private lateinit var recipeDatabase: RecipeDatabase
  @MockK private lateinit var networkClient: NetworkClient
  @SpyK private var logger = Logger()

  @Before
  fun setup() {
    MockKAnnotations.init(this)
  }

  @Test
  fun testDatabaseAndNetwork() {
    // ... use foodDatabase, recipeDatabase, networkClient and debugger
  }
}

Each property with the @MockK annotation is automatically mocked and ready to use in tests. This reduces repetition and makes your tests more readable. The above class is equivalent to:

class RepositoryTest {

  private lateinit var foodDatabase: FoodDatabase
  private lateinit var recipeDatabase: RecipeDatabase
  private lateinit var networkClient: NetworkClient
  private lateinit var logger: Logger

  @Before
  fun setup() {
    foodDatabase = mockk()
    recipeDatabase = mockk()
    networkClient = mockk()
    logger = spyk(Logger())
  }

  @Test
  fun testDatabaseAndNetwork() {
    // ... use foodDatabase, recipeDatabase, networkClient and debugger
  }
}

Options #

@MockK annotations take the same options as the mockk function. If you wish to use a relaxed mock, the annotation looks similar to the equivalent mockk call:

// Annotations
class RepositoryTest {

  @MockK(relaxed = true) private lateinit var foodDatabase: FoodDatabase
  @MockK(relaxUnitFun = true) private lateinit var recipeDatabase: RecipeDatabase

  @Before
  fun setup() {
    MockKAnnotations.init(this)
  }
}
// Long form
class RepositoryTest {

  private lateinit var foodDatabase: FoodDatabase
  private lateinit var recipeDatabase: RecipeDatabase

  @Before
  fun setup() {
    foodDatabase = mockk(relaxed = true)
    recipeDatabase = mockk(relaxUnitFun = true)
  }
}

In addition to @MockK(relaxed = true), there is an equivalent @RelaxedMockK annotation.

If options are shared across every annotated mock, they can be passed to the init call instead.

class RepositoryTest {

  @MockK private lateinit var foodDatabase: FoodDatabase
  @MockK private lateinit var recipeDatabase: RecipeDatabase

  @Before
  fun setup() {
    MockKAnnotations.init(this, relaxed = true)
  }
}

Spies #

TODO

Buy Me a Coffee at ko-fi.com