1

Supossing I have the following code to test UserController by mocking UserService (where UserController has a reference to UserService):

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
...

public class UserControllerTest {
    private final List<User> users1 = new ArrayList<>();
    private final List<User> users2 = new ArrayList<>();

    @Before
    public void initUsers() {
        User user = new User();
        user.setId(1L);
        users1.add(user);

        User user = new User();
        user.setId(2L);
        users2.add(user);
    }

    @Test
    public void testFindAlls() throws Exception {
        UserService userService = mock(UserService.class); //line1
        when(userService.findAll1()).thenReturn(users1); //line2
        when(userService.findAll2()).thenReturn(users2); //line3

        UserController userController = new UserController();
        ReflectionTestUtils.setField(userController, "userService", userService);
        List<User> users3 = userController.findAll1(); //line4
        List<User> users4 = userController.findAll2(); //line5

        ...
    }
}

I have the following doubts:

  1. When the line1 is reached, what would be the default behaviour for userService.findAll1() and userService.findAll2()?
  2. When the line3 is reached, as userService.findAll1() and userService.findAll2() return the same result type (List<User>). Will the line3 override the behaviour defined in line2? I mean, will userService.findAll1() return users2 instead of users1?
  3. I mean, the when method signature is public static <T> OngoingStubbing<T> when(T methodCall) so T in the example would be an element of type List<User> with the value probably to null. So, how the when method is able to determine that different calls are passed as arguments?
Aliuk
  • 1,249
  • 2
  • 17
  • 32

1 Answers1

2

1. When you mock something all methods - that have a return type - would just return null by default (or equivalents in case of primitives). Since the mock has no implementation on its own, a call to the method is doing nothing (basically it handles like an empty method).

2. Why would that be? You map different return values to different methods, there is no possibility of overriding something.

Edit3: I just removed my previous try to expalin this. The content of the link is better than anything I can come up with. So it's not easy to understand.

How does mockito when() invocation work?


On another note:
You might not need to use Reflections to put the mock into your object. Check out @InjectMocks & @Mock. So wheter you can use them (or how to use them) depends on your JUnit and Mockito version. (How to use Mockito with JUnit5)

second
  • 4,069
  • 2
  • 9
  • 24
  • I mean, the when method signature is `public static OngoingStubbing when(T methodCall)` so `T` in the example would be an element of type `List` with the value probably to `null`. So, how the when method is able to determine that different calls are passed as arguments? – Aliuk May 29 '19 at 10:00
  • I've updated the answer and I hope it helps in getting your confusion about some things the java language does and what mockito is actually doing. If you want to have a deeper understanding you might want to checkout the mockito implementation yourself, but that should not be necessary if you only want to write some tests. – second May 29 '19 at 10:17
  • Replaced the last edits with an more detailed answer found on this board – second May 29 '19 at 10:56
  • Thank you so much, that was exactly what I was looking for! – Aliuk May 29 '19 at 11:13