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.

  1. class RepositoryTest {
  2. @MockK private lateinit var foodDatabase: FoodDatabase
  3. @MockK private lateinit var recipeDatabase: RecipeDatabase
  4. @MockK private lateinit var networkClient: NetworkClient
  5. @SpyK private var logger = Logger()
  6. @Before
  7. fun setup() {
  8. MockKAnnotations.init(this)
  9. }
  10. @Test
  11. fun testDatabaseAndNetwork() {
  12. // ... use foodDatabase, recipeDatabase, networkClient and debugger
  13. }
  14. }

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:

  1. class RepositoryTest {
  2. private lateinit var foodDatabase: FoodDatabase
  3. private lateinit var recipeDatabase: RecipeDatabase
  4. private lateinit var networkClient: NetworkClient
  5. private lateinit var logger: Logger
  6. @Before
  7. fun setup() {
  8. foodDatabase = mockk()
  9. recipeDatabase = mockk()
  10. networkClient = mockk()
  11. logger = spyk(Logger())
  12. }
  13. @Test
  14. fun testDatabaseAndNetwork() {
  15. // ... use foodDatabase, recipeDatabase, networkClient and debugger
  16. }
  17. }

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:

  1. // Annotations
  2. class RepositoryTest {
  3. @MockK(relaxed = true) private lateinit var foodDatabase: FoodDatabase
  4. @MockK(relaxUnitFun = true) private lateinit var recipeDatabase: RecipeDatabase
  5. @Before
  6. fun setup() {
  7. MockKAnnotations.init(this)
  8. }
  9. }
  1. // Long form
  2. class RepositoryTest {
  3. private lateinit var foodDatabase: FoodDatabase
  4. private lateinit var recipeDatabase: RecipeDatabase
  5. @Before
  6. fun setup() {
  7. foodDatabase = mockk(relaxed = true)
  8. recipeDatabase = mockk(relaxUnitFun = true)
  9. }
  10. }

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.

  1. class RepositoryTest {
  2. @MockK private lateinit var foodDatabase: FoodDatabase
  3. @MockK private lateinit var recipeDatabase: RecipeDatabase
  4. @Before
  5. fun setup() {
  6. MockKAnnotations.init(this, relaxed = true)
  7. }
  8. }

Spies

TODO