Mockito is a Java mock framework. It is mainly used for mock testing. It can simulate any Spring managed bean, the return value of the simulated method, and the exception thrown. Before understanding the specific usage of mockito, you need to know what is mockito testing
1. What is mock test?
mock testing is to create a fake object during the testing process, so as to avoid that you have to build the whole bean dependency chain to test a method
As shown in the following figure, class A needs to call class B and class C, while class B and class C need to call other classes, such as D, E, F, etc. assuming that class D is an external service, it will be difficult to test, because your return results will be directly affected by the external service, which may lead to your unit test passing today, but not tomorrow
When we introduce the mock test, we can create A fake object and replace the real beans B and C, so that when we call the methods of B and C, we will actually call the methods of the fake mock object, and we can set the parameters and expected results of the mock object ourselves, so that we can focus on testing the current class A without being affected by other methods External service impact, so the test efficiency can be improved A lot
2. Introduction to mockito
Now that we're done with the concept of mock testing, let's move on to today's topic, Mockito
Mockito is a Java mock framework, which is mainly used for mock testing. It can simulate any Spring managed bean, the return value of the simulation method, the exception thrown by the simulation, etc. at the same time, it will also record the parameters and the calling order of these simulation methods, so as to check whether the mock object is called in the correct order and according to the expected order Parameter called
For example, Mockito can simulate the data returned by a service in unit test without actually calling the service. This is the above-mentioned mocking test spirit, that is, by simulating a fake service object, to quickly test the current class I want to test
At present, the mainstream mock testing tools in Java include Mockito, JMock, EasyMock... And so on. Spring boot currently builds the Mockito framework
As an aside, Mockito is named after a kind of Mojito. Foreigners also like to play homophonic stem...
3. Using Mockito in spring boot unit test
First, add a spring boot starter test dependency under pom.xml, which includes JUnit and Mockito
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
First, write a UserService. There are two methods in it: getUserById() and insertUser(). They will call the getUserById() and insertUser() methods of UserDao
@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); } }
The User model is defined as follows
public class User { private Integer id; private String name; //Omit getter/setter }
If we do not use Mockito to simulate a fake userDao bean at this time, but really call the userDao of a normal Spring bean, the test class is written as follows. In fact, it is very common to inject the userService bean, then call his method, and he will call userDao to get the data of the database, and then we will make assert check on the returned result
@RunWith(SpringRunner.class) @SpringBootTest public class UserServiceTest { //First, inject a userService bean @Autowired private UserService userService; @Test public void getUserById() throws Exception { //If you use userService, you will call userDao to get the data of the database User user = userService.getUserById(1); //Examination result Assert.assertNotNull(user); Assert.assertEquals(user.getId(), new Integer(1)); Assert.assertEquals(user.getName(), "John"); } }
But if the user Dao hasn't been written and wants to test the user service first, you need to use Mockito to simulate a fake user Dao
The way to use it is to add a @ mock bean annotation to userDao. When userDao is added with this annotation, it means that Mockito will help us create a fake mock object and replace the existing real userDao bean in Spring, that is to say, the userDao bean injected into userService has been replaced by the fake mock object. So when we When calling the userService method again, it will actually call the method of the mock userDao bean instead of the real userDao bean
When we create a fake userDao, we need to customize the return value of the method for the mock userDao. Here is a formula usage. The following code means that when a method of a mock object is called, the user-defined result we want will be returned
Mockito. When (object. Method name ()). Thenreturn (custom result)An example of unit testing using Mockito to simulate bean s is as follows
@RunWith(SpringRunner.class) @SpringBootTest public class UserServiceTest { @Autowired private UserService userService; @MockBean private UserDao userDao; @Test public void getUserById() throws Exception { // Defines that when the getUserById() method of the mock userDao is called and the parameter is 3, the user object with id 200 and name I'm mock3 is returned Mockito.when(userDao.getUserById(3)).thenReturn(new User(200, "I'm mock 3")); // It will return a user object named I'm mock 3 User user = userService.getUserById(1); Assert.assertNotNull(user); Assert.assertEquals(user.getId(), new Integer(200)); Assert.assertEquals(user.getName(), "I'm mock 3"); } }
In addition to the basic "Mockito. When" (object. Method name ()). Thenreturn (custom result), Mockito also provides other uses for us to use
thenReturn series methods
When the getUserById() method of userService is called with any integer value, a user object named I'm mock3 is returned
Mockito.when(userService.getUserById(Mockito.anyInt())).thenReturn(new User(3, "I'm mock")); User user1 = userService.getUserById(3); // The name of the returned user is I'm mock User user2 = userService.getUserById(200); // The returned user's name is also I'm mock
Limit the return of user object named I'm mock 3 only when the number of parameter is 3
Mockito.when(userService.getUserById(3)).thenReturn(new User(3, "I'm mock")); User user1 = userService.getUserById(3); // The name of the returned user is I'm mock User user2 = userService.getUserById(200); // The returned user is null
When the insertUser() method of userService is called, it returns 100 regardless of the user passed in
Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn(100); Integer i = userService.insertUser(new User()); //Will return to 100
thenThrow series methods
When the parameter of getUserById() of userService is 9, a RuntimeException is thrown
Mockito.when(userService.getUserById(9)).thenThrow(new RuntimeException("mock throw exception")); User user = userService.getUserById(9); //A RuntimeException will be thrown
If the method does not return a value (that is, the method is defined as public void myMethod() {...}), use doThrow() instead to throw an Exception
Mockito.doThrow(new RuntimeException("mock throw exception")).when(userService).print(); userService.print(); //A RuntimeException will be thrown
verify series method
Check if the number of times to call getUserById() of userService with parameter 3 is 1
Mockito.verify(userService, Mockito.times(1)).getUserById(Mockito.eq(3)) ;
Verify the calling order, and verify whether the userService calls getUserById() twice, and the first parameter is 3, and the second parameter is 5, then the insertUser() method is called
InOrder inOrder = Mockito.inOrder(userService); inOrder.verify(userService).getUserById(3); inOrder.verify(userService).getUserById(5); inOrder.verify(userService).insertUser(Mockito.any(User.class));
4. Limitation of mockito
The above is the usage of Mockito's mockobject, but when using Mockito in a mockobject, there are some limitations that need to be observed
-
Cannot mock static methods
-
Cannot mock private method
-
Can't mock final class
Therefore, when writing code, we need to do a good function splitting to use Mockito's mock technology to help us reduce the coupling of bean s during testing
5. summary
Mockito is a very powerful framework, which can help us simulate a bean when executing unit tests and improve the stability of unit tests
In addition, you can try to write code from the perspective of mock test, and you can write a code architecture with good function segmentation. For example, if you extract the code specially used to communicate with external services into a bean, you can replace the bean through Mockito during unit test
K'illCode 656 original articles published, 331 praised, 310000 visitors+ His message board follow