3

I need to verify that a method has been called on an object. So I make a spy of this object:

obj = spyk(obj)

And then I verify that a method has been called:

verify(exactly = 1) { obj.f(3) }

The test fails with the following error message:

java.lang.AssertionError: Verification failed: call 1 of 1: obj(#2).f(eq(3))) was not called.

However I can clearly see the method f being called:

  1. I can break in that method in debug mode
  2. I print out hello world from f() in that method and see it being printed.

How do I use spies correctly in mockk?

P.S.

I tried doing val obj = spyk(obj()) but I get lateinit has not been initialized error because I need to set a parameter in obj as so:

obj.setDependency(friend)

But in the case where I first do val obj = spyk(obj()) and then call obj.setDependency(friend) like I explained above I end up with a lateinit has not been initialized error

Can someone please help me resolve this issue?

Jenia Ivanov
  • 2,485
  • 3
  • 41
  • 69

2 Answers2

0

You can mock an object with Spyk, which is what I think you were trying to do with spyk(obj()):

Say you have the following viewModel:

@HiltViewModel
class MyViewModel @Inject constructor(
     myUseCase1: MyUseCase1,
     myRepository: MyRepository
) : ViewModel {

......

     fun myFun(value: Boolean) { 
         if (value) {
              myUseCase1.doSomething()
              doSomethingElse()
         }
     }

     private fun doSomethingElse() {
       //do something
     }
}

You can mock the object:

class MyViewModelTest {

     @Mockk
     val myUseCase1: MyUseCase1

     @Mockk
     val myRepository: MyRepository

     private lateinit var viewModel: MyViewModel

     @Before
     fun setUp() { 
          MockKAnnotations.init(relaxed = true)
          val viewModel = spyk(
                MyViewModel(
                   myUseCase1,
                   myRepository
                ),
                recordPrivateCalls = true
          )
     }

     @Test
     fun test1() { 
          viewModel.myFun(true)
          verify { myUseCase1.doSomething() }
          verify { viewModel.doSomethingElse() }
     }

}
         


     
Kristy Welsh
  • 7,828
  • 12
  • 64
  • 106
-1

In your case, I don't understand this part obj = spyk(obj). What are you doing here? I think this part don't even compile.

You receive lateinit has not been initialized error because spyk(obj()) calls real constructor. If your object has dependencies, you have to create them too or pass mockk instead of them.

According to the documentation:

Note: the spy object is a copy of a passed object.

You have to create this object like a normal object, so all dependencies have to be filled.

I am using spyk in this way, let me show you a quick example.

    fun `should call method testMethod`() {
    val spy = spyk<TestClass>()

    spy.testMethod(1)

    verify (exactly = 1) { spy.testMethod(1) }
}
Ice
  • 1,783
  • 4
  • 26
  • 52