6

I am using Mockito to mock a certain class while writing my test cases.

Is there a way to print some statements before returning a value? Like:

when(x.callFunction(10).thenReturn(new String("Hello"));

The above statement works, however I am not able to do the following:

when(x.callFunction(10).thenReturn({
   System.out.println("Mock called---going to return hello");
   return new String("Hello");});
GhostCat
  • 137,827
  • 25
  • 176
  • 248
user1692342
  • 5,007
  • 11
  • 69
  • 128
  • You got good answers, but: don't spend too much time on stuff like this. If you *think* you need such print statements to be able to understand what your code is doing, then my gut feeling is that you might have a "quality" problem with either your production or your test code. So, this might be worth stepping back and talking with some experienced folks about the things you are doing. – GhostCat Mar 31 '17 at 07:20
  • @GhostCat I will be using thenReturn in my final code. This is more to test my testing code and check if my mocking function is being called or not! :) – user1692342 Mar 31 '17 at 07:22

3 Answers3

8

With thenAnswer you can execute additional actions every time the mocked method is invoked.

when(x.callFunction(10)).thenAnswer(new Answer<String>() {
    public String answer(InvocationOnMock invocation)  {
        System.out.println("Mock called---going to return hello");
        return "Hello";
    }
});

See also thenAnswer Vs thenReturn.

Community
  • 1
  • 1
Roland Weisleder
  • 9,668
  • 7
  • 37
  • 59
3

If the object you're going to create is not final, then besides thenAnswer provided by @Roland Weisleder, you can just use an anonymous subclass with init block in thenReturn, like the following example code:

class FoobarFactory {
    public Foobar buildFoobar() {
        return null;
    }
}

class Foobar {
    private String name;
    public Foobar(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

with mock code as:

@Test
public void testFoobar() throws Exception {
    FoobarFactory foobarFactory = mock(FoobarFactory.class);
    when(foobarFactory.buildFoobar()).thenReturn(new Foobar("somename") {
        {
            System.out.println("Creating mocked Foobar");
        }
    });

    Foobar foobar = foobarFactory.buildFoobar();
    assertThat(foobar.getName(), is("somename"));
}
shizhz
  • 11,715
  • 3
  • 39
  • 49
  • Nice idea. But more on the "code puzzle" side of things. I wouldn't want something like that in our unit tests ... – GhostCat Mar 31 '17 at 07:21
  • Yes, `thenAnswer` will always be a better practice, just post it here to share a possibility :-) – shizhz Mar 31 '17 at 07:25
  • Funny thing; I thought further about this; and put up a completely different answer ;-) – GhostCat Mar 31 '17 at 07:32
2

I like the other answers, but given your latest comment:

I will be using thenReturn in my final code. This is more to test my testing code and check if my mocking function is being called or not!

I have another idea for you: do not return/print on that call; use thenThrow() instead!

The point is: print statements in the console are sometimes helpful; but they are easy to be overlooked. If the whole purpose is to be sure that a certain call happens on a certain mock; then just throw an exception instead of returning a value. As JUnit will give you direct and hard-to-ignore feedback on that; by failing the testcase.

You could even go one step further and put up @expected on that test - in that way you have a method to test this aspect automatically - if the mock isn't called; no exception; test will fail.

GhostCat
  • 137,827
  • 25
  • 176
  • 248