15

I have a class A with 2 functions: function a() which returns a random number. function b() which calls a() and return the value returned.

In a test I wrote this:

A test = Mockito.mock(A.class)
Mockito.when(test.a()).thenReturn(35)
assertEquals(35,test.a())
assertEquals(35,test.b())

The test fails at the second assert. Does anyone know why?

To be clear - this is not my real code, but a simple code to explain my problem

tamird14
  • 481
  • 1
  • 6
  • 19

3 Answers3

25

Since class A is mocked, all method invocations wont go to the actual object. Thats why your second assert fails (i guess it might have returned 0).

Solution:

You could do something like

when(test.b()).thenCallRealMethod();

else you could spy like

A test = spy(new A());
Mockito.when(test.a()).thenReturn(35);
assertEquals(35,test.a());
assertEquals(35,test.b());
Sajan Chandran
  • 11,287
  • 3
  • 29
  • 38
  • 1
    @SajanChandran Thank you!! Both solutions work! 2 questions: 1) For the first solution, I'll have to do thenCallRealMethod() for each function in the class? for each function with a call to a()? 2) For the second solution, what is the difference between 'mock' and 'spy'? – tamird14 Oct 14 '15 at 13:30
  • 1
    yes, if you want to use any real method you have to call `thenCallRealMethod` and see this for http://stackoverflow.com/questions/28295625/mockito-spy-vs-mock – Sajan Chandran Oct 14 '15 at 13:32
  • Its up to you to decide basically, to mock or invoke real method – Sajan Chandran Oct 14 '15 at 13:44
4

function b() which calls a()

Maybe it does in your actual concrete A, but that is not being used in this case. Only the mock is being used here.

So you need to tell the mock what to do for every method you want to call:

Mockito.when(test.b()).thenReturn(35);
weston
  • 54,145
  • 21
  • 145
  • 203
4

Because you have only a mock when you call it with test.a().

You have to add Mockito.when(test.b()).thenReturn(35). then your code works fine

Jens
  • 67,715
  • 15
  • 98
  • 113
  • So if I have a function which calls a() and does something with the returned value, and I want to test it? a() returns a random number and for the test I want it to return a fixed number I decide. How do I do it? – tamird14 Oct 14 '15 at 12:58
  • @tamird14 can not get you – Jens Oct 14 '15 at 12:59
  • lets say I have a function b() which calls a(), take the returned number and returns the reverse number (123 and 321 for example). I want to test this function. The problem is that I don't know what a() will return, because it's random. So I want to make a() return the number 123 (for example) so I could write in the test assertEquals(321,A.b()). I want to test the function when I know what a() returns in this specific case – tamird14 Oct 14 '15 at 13:06
  • @tamird14 I think what you need is something like `Mockito.doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { return 123 } }).when(test).a(); – Jens Oct 14 '15 at 13:11
  • It still fails in the second assert – tamird14 Oct 14 '15 at 13:25