ref: https://howtodoinjava.com/mockito/mockito-mock-injectmocks/
1. initMocks vs. @SpringBootTest ( 不想看这些背景介绍的可以跳过直接看2.)
1.1 在@Before中用initMocks
源码注释:Initializes object annotated with Mockito annotations for given testClass
1.1.1 先看看init mocks的多种方法:
https://examples.javacodegeeks.com/core-java/mockito/mockito-initmocks-example/
1.1.1.1 用Mocikito.mock():
- 传入的参数可以是interface或者class
LinkedList mocklinkedList = Mockito.mock(LinkedList.class);
- 当某个action被触发,返回需要的东西:
Mockito.when(mocklinkedList.get(0)).thenReturn("First Value");
- 验证
Assert.assertEquals("First Value", mocklinkedList.get(0));
Mockito.verify(mocklinkedList).get(0); // verify the invocation
1.1.1.2 用initMocks()
MockitoAnnotations.initMocks(this);
“This method is useful when you have a lot of mocks to inject. It minimizes repetitive mock creation code, makes the test class more readable and makes the verification error easier to read because the field name is used to identify the mock.”
发现:不initmocks,mock(RequestNorPermitted.class)并没有mock,而是返回了真实的exception....不对,到现在都不知道改了啥,突然mock的就不行了
1.1.1.2.1 Inject Mocks
主要参考了https://site.mockito.org/javadoc/current/org/mockito/InjectMocks.html
@InjectMocks
Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won’t report failure; i.e. you will have to provide dependencies yourself.
下面的可结合1.1.1.2.2的例子理解:
- Constructor Injection
需要被Inject的Object,其构造函数所需要的参数需要在test中被声明。如果没有被声明,则要注入的Object为null。
原文:the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. If the object is successfully created with the constructor, then Mockito won’t try the other strategies.
Note: If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won’t happen. In these cases, you will have to satisfy dependencies yourself.
- Property setter Injection
优先级:type > name
如果同一type的properties有很多,那最好给它们都起个名字
原文:mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the property name and the mock name.
Note 1: If you have properties with the same type (or same erasure), it’s better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won’t happen.
Note 2: If @InjectMocks instance wasn’t initialized before and have a no-arg constructor, then it will be initialized with this constructor.
- Field Injection
优先级:type > name
如果同一type的fields有很多,那最好给它们都起个名字
原文:Field injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the field name and the mock name.
Note 1: If you have fields with the same type (or same erasure), it’s better to name all @Mock annotated fields with th