当前位置:   article > 正文

SpringBoot + Mockito单元测试_spring boot mockito

spring boot mockito

前言

为了保证代码质量,在写完代码后,写单测是很有必要的。当然,在大部分情况下,我们可能不会写单测,而是直接把应用部署起来,直接自测,然后再联调。估计很大一部分人,都是用这种方式开发。当然,我之前也是按这个方式来开发,单测覆盖率纯粹是为了满足公司的指标要求,大部分流于形式。

写单测好处

慢慢的,我感受到写单测带来的几个好处:

1、提升效率

启动一个应用,几分钟,找bug,修bug,再重启应用。这个过程不断的重复,应用重启太浪费时间。而单测不需要重启整个应用,只对几个service做测试,效率高很多

2、场景覆盖全

单测可以对代码运行中的各种情况进行模拟,并对最终的返回结果断言,这是自己自测很难模拟的。而且,这些单测,是沉淀的资产。下次修改代码,可以重跑以前单测,发现问题,避免踩坑。

单测怎么写

我们很容易对单测产生误解,所以这里我先把2个概念说明一下:

1、集成测试

测试过程中,会启动整个Spring容器,调用DB 或者  依赖的外部接口等。只不过访问的环境是测试环境。这个过程最大程度还原生产环境过程,但是耗时长。

2、单元测试

不启动整个应用,只对单个接口/类进行测试。不调用DB 、外部接口,依赖的服务都Mock掉,只测试代码逻辑。这个过程,测试用例耗时短。

我们说的单测,是指第2种。

单测过程分2步,第一步:Mock外部依赖,第二步:断言

Mockito

Mock框架很多,我以比较熟悉的Mockito为例,介绍单测的基本过程

  1. <dependency>
  2. <groupId>org.mockito</groupId>
  3. <artifactId>mockito-core</artifactId>
  4. <version>3.3.3</version>
  5. <scope>test</scope>
  6. </dependency>
  1. @Service
  2. public class ServiceA{
  3. @Resource
  4. private DaoA daoA;
  5. @Resource
  6. private ServiceC serviceC;
  7. }

注入Mock service

1、全部Mock
@Mock
private ServiceA serviceA;

这种方式,serviceA中的所有方法都会被mock,并不会真正被调用到

2、依赖注入

ServiceA 依赖了 ServiceC 和 DaoA,使用InjectMocks可以自动注入

@InjectMocks
private ServiceA serviceA;
3、真实调用
@Spy
private ServiceC serviceC;

这种方式,调用serviceC的方法,会被真实调用

Mock非静态有返回结果方法

doNothing().when(serviceA).save(any(AbnormalTask.class));

Mock非静态无返回结果方法

Mockito.when(serviceA.getItem(any(AAA.class))).thenAnswer(invocationOnMock -> {
    
    return xxx;
});

Mock静态方法

try (MockedStatic<IdGenerator> utilities = Mockito.mockStatic(IdGenerator.class)) {
    utilities.when(() -> IdGenerator.generate(null)).thenReturn("1");
    FulfillSingleResult<Object> fulfillSingleResult = serviceA.executeTask(taskExecuteRequest);
    assertTrue(fulfillSingleResult.isSuccess());
}

需要注意的是,断言的内容需要写到try{} 代码块内部,否则会不生效。

断言返回结果

assertTrue(fulfillSingleResult.isSuccess());
assertFalse(xxx);

断言异常

@Rule
public ExpectedException thrown = ExpectedException.none();
thrown.expectMessage("xxx异常");

完整例子

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class ServiceATest {
  3. @Mock
  4. private DaoA daoA;
  5. @Mock
  6. private ServiceC serviceC;
  7. @InjectMocks
  8. private ServiceA serviceA;
  9. @Test
  10. public void testGetItem() throws Exception {
  11. Mockito.when(daoA.getItem(any(AAA.class))).thenAnswer(invocationOnMock -> {
  12. return xxx;
  13. });
  14. assertTrue(serviceA.getItem() != null);
  15. }
  16. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/366813?site
推荐阅读
相关标签
  

闽ICP备14008679号