1

It is driving me crazy why the real method getting called during setting up the mock on spy.

@Service
class A(){

 fun someMethod():String{
  println("inside real method")
  return "result"
 } 
}

test:

@SpyBean
private lateinit var a:A

@Test
fun test(){
 println("before mock")
 Mockito.`when`(a.someMethod()).doReturn("mock_result")
 println("empty test ended")
}

result:

before mock
inside real method
empty test ended

Once change from Sypbean to Mockbean then it works as expected:

@MockBean
private lateinit var a:A

@Test
fun test(){
 println("before mock")
 Mockito.`when`(a.someMethod()).doReturn("mock_result")
 println("empty test ended")
}

result:

before mock
empty test ended

Why the real method getting called while just setting up the mock? There is no direct method invocation at all in the code, the real test not even started.

edit: I tried with doReturn,thenReturn,doAnswer,thenAnswer , the result is the same: if it is a spy then the real method getting called in the initializing phase

beatrice
  • 3,684
  • 5
  • 22
  • 49
  • I can't see any invocation of `someMethod()` in your tests. When is it called? During the application instantiation? If so - the instantiation is done before even `test()` method is called, so `someMethod()` is called before it is stubbed in the `test()` method – dey Dec 08 '22 at 16:40
  • @dey That is my problem it is not called at all. But still... mockito calls it. edited the code adding before mock info printing – beatrice Dec 08 '22 at 16:42
  • but is it called from y our code? – dey Dec 08 '22 at 17:01
  • @dey nope, only created for testing purpose – beatrice Dec 08 '22 at 17:06
  • in the meantime found the solution here: https://stackoverflow.com/a/11620196/5454794 still.. totally nonsense – beatrice Dec 08 '22 at 17:08
  • 1
    I added the answer with explanation why it helped (answer for better formatting) – dey Dec 08 '22 at 17:21

1 Answers1

2

As you mentioned in the comments, the answer from here helped: Mockito: Trying to spy on method is calling the original method

Explanation:

Having this line of code:

`when`(a.someMethod()).doReturn("mock_result")`

The code is executed in that way:

  1. execute a.someMethod()
  2. pass return value to when() method

But mockito is making his "magic" (I'm not aware of implementation details), to stub the next call of this method. But you already called the real method when stubbing.

That's why using different way of stubbing is not making this effect:

doReturn("mock_result").`when`(a).someMethod()

In This case, you are not calling a.someMethod(), but you tell mockito that it has to return "mock_result" when someMethod() is called.

dey
  • 3,022
  • 1
  • 15
  • 25