程序员

优雅单测-3用Mockito轻松解决复杂的依赖问题

2020-06-30  本文已影响0人  uncle_hangzhou

1.Mockito

Mockito是GitHub上用于Java使用最广泛的Mock框架

Mockito核心解决的问题:不管是测试驱动开发,还是系统架构本身,都会带来的依赖结构复杂问题;单元测试做软件中的最小可测试单元,只应依当前单元的配置。 所有较大的系统都会有依赖复杂的问题。 此类问题就需要Mock框架来解决

2.快速上手

使用很简单一般分3部:

  1. 模拟外部依赖注入容器

  2. 执行单测

  3. 验证单测逻辑

2.1 SpringBoot环境

2.1.1 依赖配置

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <version>${springboot.version}</version>
</dependency>

2.1.2 单测用例

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = LiveReportServiceTest.Config.class)
public class LiveReportServiceTest {
    @Autowired
    ILiveReportWriteService iLiveReportWriteService;
    @MockBean
    LiveReportMapper liveReportMapper;

    @Test
    public void updateLiveStatusTest() {
        int num = iLiveReportWriteService.updateById(1L);
        Assert.assertTrue(num >= 0);
    }

    @Configuration
    static class Config {
        @Bean
        ILiveReportWriteService iLiveReportWriteService() {
            return new LiveReportWriteServiceImpl();
        }
    }
}

@MockBean,在SpringBoot中通过@MockBean注解,就可以快速装在一个Mock的Bean了。

此方式通过非常简单的方式解决了系统层级之间单测的依赖,可以用在数据层和业务层,也可以用在业务层之间的多项依赖等依赖上的问题

直接执行:

image.png

2.1.3 复杂单测用例

可以看到如果使用了SpringBoot,并且使用@MockBean可以快速解决依赖的问题。但是,Mock出的LiveReportMapper对象其实是个空壳,那么既然是mock就要知道如何通过mock的方式解决各种复杂逻辑

下面模拟2种复杂逻辑,Service层的单元测试mock依赖的另外一个Service类"InfoService" ,并且mock里面的2个方法

下面看例子:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = LiveReportServiceTest.Config.class)
public class LiveReportServiceTest {
    @Autowired
    ILiveReportWriteService iLiveReportWriteService;
 
    @Test
    public void updateLiveStatusTest() {
        int num = iLiveReportWriteService.updateById(1L);
        Assert.assertTrue(num >= 0);
    }
    
    @Test(expected = Exception.class)
    public void updateLiveStatusTest() {
        iLiveReportWriteService.remove(1L);
    }

    @Configuration
    static class Config {
        @Bean
        ILiveReportWriteService iLiveReportWriteService() {
            return new LiveReportWriteServiceImpl();
        }
        
        @Bean
        InfoService getLiveInfoService() throws LiveException {
            LiveInfoPO liveInfoPO = new LiveInfoPO(111L);
            liveInfoPO.setTime(System.currentTimeMillis());
            InfoService mock = Mockito.mock(InfoService.class);
            
            Mockito.when(mock.queryLiveInfoByLiveNo(Mockito.anyString())).thenReturn(liveInfoPO);
            Mockito.when(mock.removeById(Mockito.anyString())).thenThrow(new Exception());
            return mock;
        }
    }
}

2.2 非SpringBoot环境

如果没有SpringBoot环境的Starter,可以直接使用Mockito。 除了@MockBean不能使用其他功能不受影响,参考上面例子

2.2.1 依赖配置

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-all</artifactId>
</dependency>

更多用法参考Mockito官方文档,此处不做赘述

官网地址:https://site.mockito.org/

上一篇下一篇

猜你喜欢

热点阅读