Mockit如何处理静态方法

1、导入依赖

<dependency>
    <groupId>org.powermockgroupId>
    <artifactId>powermock-module-junit4artifactId>
    <version>2.0.0version>
    <scope>testscope>
dependency>
<dependency>
    <groupId>org.powermockgroupId>
    <artifactId>powermock-api-mockito2artifactId>
    <version>2.0.0version>
    <scope>testscope>
dependency>

2、代码展示

1、需要单测的方法:

补充说明:getSession是静态方法

 public List<SubjectDTO> getSubjectTree() {
        SecurityUserInfo securityUserInfo = (SecurityUserInfo) ServletUtils.getSession().getAttribute(Constants.SESSION_USER);
        String username = StringUtils.isEmpty(securityUserInfo.getUserName()) ? "anonymous" : securityUserInfo.getUserName();
        List<SubjectDTO> list;
        //查询缓存数据
        String subjectJson = redisUtils.get(subjectTreeKey);
        if (StringUtils.isNotBlank(subjectJson)) {
            list = JSONUtils.toObjectArray(subjectJson, SubjectDTO.class);
            return list;
        }

        //查询资产系统 主题信息
        list = metadataService.findSubjectAllTree();
        return list;
    }

2、对应的单测

@Slf4j
@RunWith(PowerMockRunner.class)
@PrepareForTest({ServletUtils.class})
public class StatementServiceImplTest {
    @Mock
    private MetadataService metadataService;
    @Mock
    private RedisUtils redisUtils;
    @InjectMocks
    private StatementServiceImpl statementService;

	@Test
    public void getSubjectAllTreeTest() {
		//也可以使用MockitoAnnotations.initMocks(this);来注入你所有的@Mock
        Mockito.when(redisUtils.get(any())).thenReturn("");
        Mockito.when(metadataService.findSubjectAllTree()).thenReturn(Arrays.asList(new SubjectDTO()));
		//你需要用到的静态方法的类ServletUtils
        PowerMockito.mockStatic(ServletUtils.class);
        // 模拟 getSession 方法返回的对象
        HttpSession mockSession = mock(HttpSession.class);
        //用到的静态方法getSession
        PowerMockito.when(ServletUtils.getSession()).thenReturn(mockSession);
        SecurityUserInfo securityUserInfo = new SecurityUserInfo();
Mockito.when(mockSession.getAttribute("securityUserInfo")).thenReturn(securityUserInfo);
        List<SubjectDTO> subjectAllTree = statementService.getSubjectTree();
        Assert.assertTrue(!CollectionUtils.isEmpty(subjectAllTree));
    }
}

3、静态方法mock的几个关键要素如下:

3.1、在正常的RunWith注解后多一个PrepareForTest注解,把你要用到的静态方法对应的类写到里面。

@RunWith(PowerMockRunner.class)
@PrepareForTest(YourClassWithStaticMethods.class)

3.2、mockStatic中写要用到的静态方法对应的类;when里面写类调用你的静态方法

mockStatic(YourClassWithStaticMethods.class);
when(YourClassWithStaticMethods.yourStaticMethod(any())).thenReturn(yourMockedValue);

3.3、要给mock出来的对象赋值需要**“正确”**那样。原因是mock出来的mockSession对象是由 Mockito 提供的 mock 方法生成的,而这些对象的行为和状态都是由 Mockito 管理的。“错误”的那样是不会保留实际的状态和行为。
错误:

// 模拟 getSession 方法
HttpSession mockSession = mock(HttpSession.class);
SecurityUserInfo securityUserInfo = new SecurityUserInfo();
mockSession.setAttribute("securityUserInfo",securityUserInfo);

正确:

 HttpSession mockSession = mock(HttpSession.class);
        //用到的静态方法getSession
        PowerMockito.when(ServletUtils.getSession()).thenReturn(mockSession);
        SecurityUserInfo securityUserInfo = new SecurityUserInfo();
Mockito.when(mockSession.getAttribute("securityUserInfo")).thenReturn(securityUserInfo);

总结

以上是我个人(小白)对于静态方法单测的使用的记录,如果能帮到大家就很开心。谢谢大家

你可能感兴趣的:(java)