Mockito is a Java mock frameworks, he was mainly used for mock tests, he can simulate any Spring-managed bean, the return value of simulation method to simulate throwing an exception ... and so on, until we know Mockito specific usage, must first understand what is a mock test
1. What is the mock test?
mock test is in the testing process, create a fake object, in order to test a method to avoid you, have to rely on their own to build the entire chain of bean
FIG less like this, need to call the class A and class B Class C, and Class B and Class C and needs to call other classes, such as D, E, F, etc., of Hypothesis D is an external service, it would be difficult to measure because your return will be directly affected by the results of the external service impact, cause your unit tests may be over today, but tomorrow it could not pass up
And when we introduce mock tests, you can create a fake object, replacing the real bean B and C, so call B, and C method, in fact, it would be to call the fake mock object methods, and we can set their own parameters and expected results of the mock object, so that we can focus on testing the current class a, and other external services will not be affected, so the test can improve the efficiency of many
2. Mockito Profile
Having the concept of mock tests, then we enter into today's topic, Mockito
Mockito is a Java mock frameworks, he mainly used for mock tests, he can simulate any Spring-managed bean, the return value of simulation method to simulate throwing an exception ... and so on, he will also call these analog recording method parameters, calling sequence, which can verify whether the object has been mock calls the correct order, and a call in accordance with desired parameters
Mockito can simulate such a service return data in unit tests, but not really to call the service, this is the spirit of mock tests mentioned above, that is, by simulating a fake service objects, to quickly test current I I want to test class
There Mockito, JMock, EasyMock .. in Java and other mainstream mock test tools, and built-in SpringBoot current framework is Mockito
Digression say something, Mockito is named from one mojito cocktails (Mojito), foreigners playing homophonic terrier. . .
3. In the test unit SpringBoot Mockito
First, the new spring-boot-starter-test relies at pom.xml, within which there is dependency contains JUnit, Mockito
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
First written a UserService, he there are two methods getUserById()
and insertUser()
, while they were going to go call UserDao the bean getUserById()
and insertUser()
methods
@Component
public class UserService {
@Autowired
private UserDao userDao;
public User getUserById(Integer id) {
return userDao.getUserById(id);
}
public Integer insertUser(User user) {
return userDao.insertUser(user);
}
}
User model is defined as follows
public class User {
private Integer id;
private String name;
//省略 getter/setter
}
If this is not the first time we use Mockito simulate a fake userDao bean, but really to call a normal Spring bean of userDao then test class written as follows. Is actually very common injection userService bean, then to call his methods, and he would call again userDao obtain data from a database, and then we return to the results do assert assertion checks
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
//先普通的注入一个userService bean
@Autowired
private UserService userService;
@Test
public void getUserById() throws Exception {
//普通的使用userService,他里面会再去调用userDao取得数据库的数据
User user = userService.getUserById(1);
//检查结果
Assert.assertNotNull(user);
Assert.assertEquals(user.getId(), new Integer(1));
Assert.assertEquals(user.getName(), "John");
}
}
But if userDao not write, want to first test userService, then you need to use to simulate a fake Mockito out userDao
Usage is a plus on userDao @MockBean
notes, when userDao been added to this annotation indicating Mockito will help us create a fake mock object, replacing the real userDao bean Spring already exists, that is, injection userService into the userDao bean, we have been replaced with a fake mock objects, so when we call the method userService again, will go to the call actually mock userDao bean's method, rather than a true userDao bean
When we create a fake userDao, we need userDao for the mock custom method return values, there is a formula usage, the meaning is the following code, when you call a method of a mock object, and returned customize pass the results we want
Mockito.when( 对象.方法名() ).thenReturn( 自定义结果 )
Use Mockito simulation bean unit tests the following specific examples
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@MockBean
private UserDao userDao;
@Test
public void getUserById() throws Exception {
// 定义当调用mock userDao的getUserById()方法,并且参数为3时,就返回id为200、name为I'm mock3的user对象
Mockito.when(userDao.getUserById(3)).thenReturn(new User(200, "I'm mock 3"));
// 返回的会是名字为I'm mock 3的user对象
User user = userService.getUserById(1);
Assert.assertNotNull(user);
Assert.assertEquals(user.getId(), new Integer(200));
Assert.assertEquals(user.getName(), "I'm mock 3");
}
}
Mockito addition to the basic Mockito.when( 对象.方法名() ).thenReturn( 自定义结果 )
, also offers other usage allows us to use
thenReturn series method
When using any integer value when calling userService of getUserById () method, it returns a name for the object I'm user of mock3
Mockito.when(userService.getUserById(Mockito.anyInt())).thenReturn(new User(3, "I'm mock"));
User user1 = userService.getUserById(3); // 回传的user的名字为I'm mock
User user2 = userService.getUserById(200); // 回传的user的名字也为I'm mock
Only when the limit is three numerical parameters, will return I'm mock user name for the object 3
Mockito.when(userService.getUserById(3)).thenReturn(new User(3, "I'm mock"));
User user1 = userService.getUserById(3); // 回传的user的名字为I'm mock
User user2 = userService.getUserById(200); // 回传的user为null
When you call userService of insertUser () method, regardless of what passed in user that all return 100
Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn(100);
Integer i = userService.insertUser(new User()); //会返回100
thenThrow series method
When the parameter when calling userService of getUserById () is 9:00, throws a RuntimeException
Mockito.when(userService.getUserById(9)).thenThrow(new RuntimeException("mock throw exception"));
User user = userService.getUserById(9); //会抛出一个RuntimeException
If the method does not return a value, then (that is defined as the method public void myMethod() {...}
) to use doThrow () throws Exception
Mockito.doThrow(new RuntimeException("mock throw exception")).when(userService).print();
userService.print(); //会抛出一个RuntimeException
verify Series Methods
Check the call userService of getUserById (), and the parameters for the number 3 is 1 times
Mockito.verify(userService, Mockito.times(1)).getUserById(Mockito.eq(3)) ;
Calling sequence verification, verify userService first call getUserById () twice, and the first parameter is 3, the second parameter is 5, then call insertUser () method
InOrder inOrder = Mockito.inOrder(userService);
inOrder.verify(userService).getUserById(3);
inOrder.verify(userService).getUserById(5);
inOrder.verify(userService).insertUser(Mockito.any(User.class));
4. Mockito restriction
Mockito of the above is to use mock objects, but when Mockito in the mock objects, there are some restrictions need to comply
-
You can not mock static methods
-
You can not mock private methods
-
You can not mock final class
Therefore, when writing code, to do good functional split, to be able to use the mock Mockito technology to help us reduce the coupling of the bean test
5. Summary
Mockito is a very powerful framework that can help us in the implementation of unit test simulates a bean, to improve the stability of unit testing
And you can try to write code to write from the perspective of mock tests, and more able to write good code structure segmentation function, such as if there is the dedicated service and external communication code to extract into a bean, making unit when testing, as long as the replacement of the bean through Mockito out on the line