How to properly mock properties that will be used in init block?

3.1k views Asked by At

When we create a new class A in test it inits our values and in the init block that values are passed to the class B, only after that the values getters are mocked.

The main problem is that I want to pass the mocked values to class B in init block.

Why do I need that?

Assume that class A implements some Callback that is triggered by class B inner logic of which is using these Vals and we need to test the contract between these classes.

class A(
    private val b: B
) {

    val val1: SomeVal = SomeVal()
    val val2: SomeVal = SomeVal()

    init {
        b.setVals(val1, val2)
    }
    
    fun doSomeWork() {
        b.doAnotherWork()
    }
}

classB {

    private lateinit var val1: SomeVal
    private lateinit var val2: SomeVal

    fun setVals(a: SomeVal, b: SomeVal>) {
         val1 = a
         val2 = b
    }

    fun doAnotherWork(): Int {
         return val1.SomeInt + val2.SomeInt
    }
}

class ATest {
    
    private lateinit var a: A
    private lateinit var val1: SomeVal
    private lateinit var val2: SomeVal     

    @Before
    fun setup() {
        val b = mockk<B>()

        a = spyk(A(b))

        val1 = mockk(relaxed = true)
        val2 = mockk(relaxed = true)
    
        every { a.val1 } returns val1
        every { a.val2 } returns val2
    }

    @Test
    fun test() {
        every { val1.SomeInt } returns 4
        every { val2.SomeInt } returns 6

        *someAssertion*
    }
}
0

There are 0 answers