首页 > 其他分享 >Mockito提升单元测试覆盖率

Mockito提升单元测试覆盖率

时间:2024-09-22 17:50:55浏览次数:1  
标签:Spy 覆盖率 sysLoginService Mockito 单元测试 Test sysRecordLogService class

简单实战     1、准备工作    从gitee下载一个例子工程,下面会在这个工程下补充测试用例

        

  选择的是 Ruoyi的后台代码,gitclone之后,添加几个依赖,因为习惯用

@RunWith(MockitoJUnitRunner.class) 的方式,就添加了下面的两个依赖

 

 第一个Mockito是这篇文章的主题,第二个junit4能让我使用

@RunWith(MockitoJUnitRunner.class)的方式
也能使用Springboot自带的test,但对我来说有亿点点细节,偏离主题。

  

2、编写基本架子

 

 @InjectMock标注测试哪个类,比如这里是测试 TokenController类,因为TokenController中的方法要用到StringUtils的静态方法,在每个测试方法之前mock下静态的工具类,需要在每次测试之后close一下,不然接下来的@Test方法会报错。我讲究是能一下子通过一个Controller方法就把之后的代码行给覆盖到(当然大佬听到这话至少有三句话要说...),所以SysLoginService的类我使用@Spy,@Spy能执行被注解类的方法里。TokenService是二方包里的,我用@Mock注解。

3、业务代码的逻辑

以TokenController 的logout方法为例

 接收的参数是HttpServletRequest,这个直接Mock,无需new,不然要实现许多没用的方法;首先是静态类 SecurityUtils.getToken,第二行是StringUtils.isNotEmpy,要让它走进里面,这行必须为true,或者SecurityUtils.getToken设置return一个值;之后是jwtUtils.getUserName(token),这行必须返回个userName,供下面的sysLoginService.logout使用,然后是AuthUtil.logoutByToken,没有返回值,直接doNothing()就行,接下来就是sysLoginService.logout,SysLoginService我用的@Spy,目的就是能从Conroller类覆盖到Service类,还需要看下它里面的逻辑,之后是R.ok()无需赘言。

 SysLoginService 里的logout只有一行逻辑,使用的类RecordLogService,它也在当前项目中,我也要让它的recordLogininfor方法覆盖到。如果在运行单元测试的时候能运行到RecordLogService呢,这个类是跟SysLoginService关联的,在这个测试方法中,没有直接跟TokenController直接关联,所以在@Spy RecordLogService后,还得使用,如下:

 ReflectUtils.setFieldValue(sysLoginService, "recordLogService", sysRecordLogService); 通过反射将 sysRecordLogService注入到sysLoginService中

看下 sysRecordLogService.recordLogininfor的逻辑

 没有什么特殊,remoteLogService是二方包里的方法,只需要将它的Mock对象通过ReflectionUtils set到sysRecordLogService中。

 

4、单元测试代码

 完整代码:

@RunWith(MockitoJUnitRunner.class)
public class TokenControllerTest {
  // MockedStatic 是业务逻辑中要用的的工具类,需要mocked一下
MockedStatic<SecurityUtils> mockedStaticSecurityUtils;
MockedStatic<JwtUtils> mockedStaticJwtUtils;
MockedStatic<AuthUtil> mockedStaticAuthUtil;
  // 这个是上面AuthUtil要依赖的,static new 了一下,new的过程中用到了SpringUtils.getBean的方法,这个也需要mock,并且mock getBean这个方法
MockedStatic<SpringUtils> mockedStaticSpringUtils;
@Spy
private SysRecordLogService sysRecordLogService;
@Spy
private SysLoginService sysLoginService;
@Mock
private RemoteLogService remoteLogService;
@InjectMocks
private TokenController tokenController;
@Before // 每个用@Test标注的方法之前执行
public void setup() {
mockedStaticJwtUtils = Mockito.mockStatic(JwtUtils.class);
mockedStaticSecurityUtils = Mockito.mockStatic(SecurityUtils.class);
mockedStaticSpringUtils = Mockito.mockStatic(SpringUtils.class);
mockedStaticSpringUtils.when(() -> SpringUtils.getBean(eq(Class.class))).thenReturn(null);
mockedStaticAuthUtil = Mockito.mockStatic(AuthUtil.class);
ReflectUtils.setFieldValue(sysLoginService, "recordLogService", sysRecordLogService);
ReflectUtils.setFieldValue(sysRecordLogService, "remoteLogService", remoteLogService);
}
@After // 每个用@Test标注的方法之后执行
public void after() {
     // 每次@Test的方法执行后都必须close一下,不然之后的@Test方法报错
mockedStaticJwtUtils.close();
mockedStaticSecurityUtils.close();
mockedStaticAuthUtil.close();
mockedStaticSpringUtils.close();
}
@Test
public void should_logout_ok_when_username_and_password_ok() {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
mockedStaticSecurityUtils.when(() -> SecurityUtils.getToken(request)).thenReturn("111");
mockedStaticJwtUtils.when(() -> JwtUtils.getUserName("111")).thenReturn("111");
tokenController.logout(request);
verify(remoteLogService).saveLogininfor(Mockito.any(), eq(SecurityConstants.INNER));
}
}

 5、SHOWTIME

 

 

 

 

 

 

标签:Spy,覆盖率,sysLoginService,Mockito,单元测试,Test,sysRecordLogService,class
From: https://www.cnblogs.com/hotMemo/p/18341139

相关文章

  • Java笔试面试题AI答之单元测试JUnit(7)
    文章目录37.请列举一些JUnit扩展?1.参数化测试2.条件测试执行3.临时目录4.时间测试5.重复测试6.前置/后置条件7.Mockito8.SpringTest9.JUnitVintage10.Testcontainers11.自定义注解和扩展12.测试监听器(TestListener和RunListener)38.请列举Java程序员......
  • java 中使用Mockito 时@MockitoSettings的作用是什么
    @MockitoSettings注解是Mockito框架的一部分,用于自定义Mockito的配置。它允许你通过注解的方式,调整默认的Mockito行为和设置,而无需在每个测试中编写配置代码。此注解可以与JUnit5一起使用,结合@ExtendWith(MockitoExtension.class)来增强测试的灵活性。@MockitoSettin......
  • JUnit 与 Mockito:了解差异以及如何一起使用它们
    当谈到Java生态系统中的测试时,有两个框架脱颖而出:JUnit和Mockito。两者都是开发人员工具包中的必备工具,但它们有不同的用途。在这篇文章中,我们将深入探讨JUnit和Mockito之间的差异,探索它们如何相互补充,并讨论一起使用它们的最佳实践。什么是JUnit?JUnit是一个功能强大的测......
  • Python 单元测试详解:Unittest 框架的应用与最佳实践
    Python单元测试详解:Unittest框架的应用与最佳实践文章目录Python单元测试详解:Unittest框架的应用与最佳实践一什么是Unittest1不使用Unittest测试框架2使用Unittest测试框架二unittest使用建议1先写测试case后写测试逻辑2测试文件以_test.py结尾......
  • 代码世界的守护者:单元测试的艺术与科学
    ......
  • MVC应用单元测试以及请求参数的验证
    SpringMVC支持对Controller单元测试@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={ "classpath:mvc-dispatcher-servlet.xml",})@WebAppConfigurationpublicclassControllerJUnitBase{ @Resource privateRequestMappingHandler......
  • Java笔试面试题AI答之单元测试JUnit(4)
    文章目录19.简述JUnitorg.junit.TestSuite类的作用?1.组织测试类2.简化测试执行3.灵活配置测试环境4.嵌套测试套件注意事项20.在JUnit中@Test注释的作用和用法?作用用法21.简述Junit基础注解(@BeforeClass、@Before、@Test、@After、@AfterClass)?22.编写代......
  • 5-【JavaWeb】JUnit 单元测试及JUL 日志系统
    1.使用JUnit进行单元测试JUnit是Java中非常流行的单元测试框架,MyBatis与JUnit可以很好地结合,来测试持久层代码的正确性。1.1添加JUnit依赖在使用JUnit之前,需要在pom.xml中引入JUnit依赖。<dependency><groupId>junit</groupId><artifactId>......
  • 单元测试,Junit,反射,注解(元注解,自定义注解,解析注解),动态代理
    目录一、单元测试二、反射1.认识反射2.获取类3.获取类的构造器4.获取类的成员变量5.获取类的成员方法6.作用三、注解1.概述、自定义注解2.元注解3.注解的解析四、动态代理1.概述2.使用代理的好处一、单元测试单元测试就是针对最小的功能单元(方法),编写测试代码对......
  • Java中的负载测试:从单元测试到集成测试的完整覆盖策略
    Java中的负载测试:从单元测试到集成测试的完整覆盖策略大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊一聊Java中的负载测试。负载测试是保证系统性能和稳定性的重要手段,而完整的测试策略不仅包括单元测试,还要覆盖到集成测试。本文将从单......