Java Unit Test Powermockito and Mockito Use Summary
- 2021-11-10 09:28:26
- OfStack
Use of PowerMockito
Use mockito for mock instances
Static invocation of Redis by mock
mock singleton class
mock Private Method
PowerMock Skip Method Execution
Summarize
Reference document
Recently, the company is promoting the unit test of Java application, which requires that the coverage rate of unit test be increased to over 50% to ensure that the online code is fully self-tested. Company unit testing framework selected Junit 4.12, Mock framework selected Mockito and PowerMock, and selected JaCoCo to do coverage testing, the following details of my use of these frameworks 1 experience.
Dependency introduction
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
Use of PowerMockito
The popular Mock frameworks such as Mockito, EasyMock and JMock have a common disadvantage. Neither mock static, final, private method, etc., PowerMock can perfectly solve the shortcomings of the above framework. Next, let's take a look at how the omnipotent PowerMock solves the above problems. Let's look at an example first. The following code is a class that needs to be tested. The tested class not only calls Spring Bean, but also includes static reading of Redis, and also uses getInstance () singleton class. Now, let's come to the above external class of mock on 11.
Single test class (mainly test queryStudentScoreByKeyword method)
@Component
public class StudentService {
@Resource
private StudentDao studentDao;
public List<StudentBo> queryStudentScoreByKeyword(String name) {
System.out.println("invoke StudentService.queryStudentScoreByKeyword ...");
List<StudentBo> cacheList = RedisUtils.getArray(name, StudentBo.class);
if (CollectionUtils.isNotEmpty(cacheList)) {
return cacheList;
}
String keyword = processKeyword(name);
List<Student> students = studentDao.queryStudentByKeyWord(keyword);
List<Integer> ids = students.stream().map(Student::getId).collect(Collectors.toList());
List<Person> personList = SchoolManageProxy.getInstance().queryPerson(ids);
List<StudentBo> studentBos = CommonUtils.toBo(personList, students);
// Highlight the result
highlightResult(studentBos, name);
// Cache to Redis
RedisUtils.setArray(name, studentBos, 10 * 60);
return studentBos;
}
private String processKeyword(String name) {
System.out.println("invoke StudentService.processKeyword ...");
String newName = name;
// do somethings
return newName;
}
private void highlightResult(List<StudentBo> result, String name) {
System.out.println("invoke StudentService.highlightResult ...");
// do keyword highlight
}
}
Single test class
@RunWith(PowerMockRunner.class)
@PrepareForTest({SchoolManageProxy.class, RedisUtils.class, StudentService.class})
// @PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
@SuppressStaticInitializationFor({"cn.ganzhiqiang.ares.unittest.SchoolManageProxy"})
public class StudentServiceTest {
@Mock
private StudentDao mockStudentDao;
@InjectMocks
private StudentService studentServiceUnderTest;
@Before
public void setUp() {
initMocks(this);
}
@Test
public void testQueryStudentScoreByKeyword() throws Exception {
studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
PowerMockito.mockStatic(RedisUtils.class);
PowerMockito.mockStatic(SchoolManageProxy.class);
// mock Singleton call
SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());
// mock Drop right Redis Static invocation of
PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
// Displayed mock Drop the static void The method of (you can not mock )
PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());
// mock Private method processKeyword
PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());
// Skip private methods highlightResult Execution of
PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));
// Use Mockito Come mock Invoke of service
when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());
// Run the test
final List<StudentBo> result = studentServiceUnderTest.queryStudentScoreByKeyword("tom");
}
}
Use mockito for mock instances
First, we use Mockito to call Spring Bean. Mockito. mock can be used for mock1 instances. We use @ Mock annotation here, and the effect is one.
// Use Mockito Come mock Invoke of service
when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());
Static invocation of Redis by mock
Next, we use PowerMock to use mock to call static methods. Note that we need to add RedisUtils class to @ PrepareForTest annotation. We have mock getArray method and mock setArray method. In fact, setArray does not need mock explicit mock here
PowerMockito.mockStatic(RedisUtils.class);
// mock Drop right Redis Static invocation of
PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
// Explicit mock Drop the static void The method of (you can not mock )
PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());
mock singleton class
mock singleton class is relatively complex 1 point, logically, first use Powermock mock singleton class, and then give the singleton class getInstance method piling, return to the previous mock, and then pile the method actually called by mock class. The code is as follows
PowerMockito.mockStatic(SchoolManageProxy.class);
// Powermock mock Singleton class
SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
// For singleton classes getInstance Method piling
PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
// Right mock Class queryPerson Method of piling
when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());
mock Private Method
It can be seen that the queryStudentScoreByKeyword method calls the private method processKeyword of this class. If this method takes too long, powermock can also be used for mock. It should be noted that studentServiceUnderTest needs spy () for mock
// mock Instances
// spy The standard is: If you don't pile, the real method is executed by default, and if you pile, you return to the pile implementation.
studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
// mock Private method processKeyword
// doReturn(...) when(...) Do not make real calls, but when(...) thenReturn(...) The original method is actually called, but the specified result is returned
PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());
PowerMock Skip Method Execution
You can also skip the execution of private methods with PowerMock
// Skip private methods highlightResult Execution of
PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));
Summarize
I seldom write single test when writing code before. Since the company forced to improve the coverage rate of single test, although the development efficiency slowed down, it really caused me to pay attention to single test, and then studied Mock frameworks such as PowerMockito and Mokcito. Powermock is all-powerful because it uses custom loaders and bytecode manipulation techniques. At the same time, it is 10 points easy to use, and it is really an excellent framework.
Demo Address: https://github.com/LJWLgl/mock-data
Reference document
PowerMock
In-depth practice of powermockito unit testing
Talking about PowerMock of test
Omnipotent PowerMock, mock private method, static method, test private method, final class
Differences between Mock and Spy