1

I need to be able to call a real method of spy object based on some condition. I.e. if condition is true then call real method otherwise do something else.

To be clear, I need to throw an exception on first call and call real method on a second call. Is it possible to achieve by using Mockito?

Object object = Mockito.spy(new Object());

// On the first call I need to throw an exception like this
Mockito.doThrow(RuntimeException.class).when(object).toString();

// On the second call I need to call a real method
Mockito.doCallRealMethod().when(object).toString();
Oleksandr
  • 3,574
  • 8
  • 41
  • 78

1 Answers1

1

Easy, use when(...).then(...), as that allows for "fluent chaining" of mock specifications:

Object object = Mockito.spy(new Object());
Mockito.when(object.toString()).thenThrow(new RuntimeException()).thenReturn("yeha");

try {
  System.out.println(object.toString());
  fail();
} catch(RuntimeException r) {
  System.out.println(object.toString());
}

Prints:

yeha

Yeha!

Seriously: you should prefer when(mock.foo()).then... anyway (see here for a list of reasons why that is). There are a few situations where doReturn().when() needs to be used, but as said: it is your last resort, not your first choice.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    Thank you very much for the answer! It is what I need! – Oleksandr Mar 15 '19 at 20:29
  • 1
    This is not the answer unfortunately - using this methodology the Spied class will call the real method whilst setting up the mock. This may not be appropriate. – yeti_c Nov 10 '22 at 23:53