具有相同返回类型的方法的Mockito默认行为和自定义行为

时间:2019-05-29 09:39:01

标签: java unit-testing reflection junit mockito

假设我有以下代码通过模拟UserController(其中UserService引用了UserController)来测试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

        ...
    }
}

我有以下疑问:

  1. 到达第1行时,userService.findAll1()userService.findAll2()的默认行为是什么?
  2. 到达第3行时,userService.findAll1()userService.findAll2()返回相同的结果类型(List<User>)。第3行会否覆盖第2行中定义的行为?我的意思是,userService.findAll1()将返回users2而不是users1吗?
  3. 我的意思是,when方法签名为public static <T> OngoingStubbing<T> when(T methodCall),因此示例中的T将是类型为List<User>的元素,其值可能为null 。因此,when方法如何确定不同的调用作为参数传递?

1 个答案:

答案 0 :(得分:2)

1。 当您模拟某些东西时,所有具有返回类型的方法默认情况下都将返回null(对于原语,则为等效方法)。由于该模拟本身没有实现,因此对该方法的调用无济于事(基本上像空方法一样进行处理)。

2。 为什么会这样呢?您将不同的返回值映射到不同的方法,就不可能覆盖某些东西。

Edit3: 我只是删除了以前的尝试对此进行解释。链接的内容比我能提出的要好。所以这不容易理解。

How does mockito when() invocation work?


另外一个说明:
您可能不需要使用反射将模拟对象放入对象中。查看@InjectMocks和@Mock。因此,您能否使用它们(或如何使用它们)取决于您的JUnit和Mockito版本。 (How to use Mockito with JUnit5