5

We currently have an object that consists of constant values only.

object Constants {
    const val VERSION = V1
}

However, these constants' values may be altered in the future. Thus I want to ensure that a test breaks if certain conditions are not met by the VERSION value. We use Mockk for mocking so I tried to mock the Constants object according to the docs like this

mockkObject(Constants)
every { Constants.VERSION } returns -1
assertThat(Constants.VERSION).isEqualTo(-1)

Unfortunately this does not compile with the following error: io.mockk.MockKException: Missing calls inside every { ... } block.

Is there a way to mock the constant value? Or should I provide getter methods for the constants and mock these?

Robin Ellerkmann
  • 2,083
  • 4
  • 29
  • 34

3 Answers3

5

Constants in kotlin don't have getters which is the reason behind your exception: io.mockk.MockKException: Missing calls inside every { ... } block. There is no function which can be mocked to retrieve the value.

I would suggest you rethink your goal of testing constants (which is not a typical test case), or to make a workaround. Workarounds could be:

  • Create a getter for each constant you want to mock
  • Put Constants inside an other class, which would return Constants object and you could test every field (with assertJ fieldByField)
  • Put const values inside a text or properties file which can be tested
Neo
  • 1,869
  • 1
  • 7
  • 20
0

One possibility is to use Whitebox from PowerMockMockito; yes, you can use Whitebox together with MockK. The advantage of Whitebox is that you have the freedom of setting a constant to any value you'd like without the hassle of creating wrapper classes which are useless except for unit tests.

Example:

import org.powermock.reflect.Whitebox

Whitebox.setInternalState(Constants::class.java, (Constants::VERSION).name, 1)
Yida Lin
  • 167
  • 2
  • 10
0

You can replace constants with enum class and then mock them with MockObject. For example:

class MyClass {

enum class MyConstants( val param: String ) {
VERSION( "V1" ),
TEMP_FOLDER_PATH( "usr/temp/");
   }

 //to use in code:
 var tempFolder : String = MyConstants.TEMP_FOLDER_PATH.param
} 

To mock it later in unit tests:

 mockObject( MyClass.MyConstants.TEMP_FOLDER_PATH )
 every { MyClass.MyConstants.TEMP_FOLDER_PATH.param } returns "whatever is needed"
Interkot
  • 697
  • 8
  • 10