搭建大型分布式服务(四十六)利用mockito不启动SpringBoot项目下进行单元测试

系列文章目录


文章目录

  • 系列文章目录
  • 前言
      • 一、本文要点
      • 二、开发环境
      • 三、编写真实类
      • 四、编写测试类
      • 四、小结


前言

SpringBoot支持集成Mockito做单元测试,有时候SpringBoot有很多外部依赖,在本地很难启动或者启动时间很长,而我们只想对某个方法进行测试,需要怎样做呢?


一、本文要点

接前文,我们已经已介绍在两种mock模式下,怎样根据入参返回自定义mock结果,但都是通过启动SpringBoot项目来运行的。本文将介绍不启动SpringBoot的情况下运行单元测试。
系列文章完整目录

  • SpringBooot 单元测试
  • Mockito 单元测试
  • Mock、Spy 单元测试
  • InjectMocks 注入深层依赖

二、开发环境

  • jdk 1.8
  • maven 3.6.2
  • springboot 2.4.3
  • idea 2020
  • junit5
  • Mockito

三、编写真实类

1、编写真实Service类TagService.java,它依赖ElasticeService类,模拟真实应用场景。

@Slf4j
@Getter
@Service("tagService")
public class TagService {

    // 操作远程ES工具类
	private ElasticeService elasticService;
	
	// 依赖ES工具类实现逻辑
    public String listTags(String bId) {
        return elasticService.list(bId);
    }
}

2、编写真实service类ElasticService.java,它依赖restHighLevelClientProxy类,模拟操作es工具类。

@Slf4j
@Getter
@Service("elasticService")
public class ElasticeService {

	@Resource
	private RestHighLevelClientProxy proxy;
	
	// 依赖ES工具类实现逻辑
    public String listTags(String bId) {
        // 远程调用
        SearchResponse searchResponse = restHighLevelClientProxy.search(bId);
        // 其他逻辑
        return "";
    }
}

四、编写测试类

1、@InjectMocks 用来注入依赖类,这里不再使用SpringExtension启动单元测试类,而是使用MockitoJUnitRunner类。

@Slf4j
@ActiveProfiles("dev")
@RunWith(MockitoJUnitRunner.class)
class TagServiceTest {

    /**
     * 这里使用MockBean,tagService中所有方法都会被mock掉.
     */
    @InjectMocks
    private TagService tagService;
    
    // 依赖的操作远程ES工具类,直接mock掉
    // @Mock跟上一篇文章介绍的@MockBean类似
    @Mock
	private ElasticeService elasticService;

   @Before
    public void setup() {
    	// 启用注解
        MockitoAnnotations.initMocks(this);
    }

	
    @Test
    void buildTagName() {

      Mockito.when(elasticService.listTags(Mockito.any())
                .thenReturn(mockResult());
                
        String bid = "45345xclm34kxjL";

        log.info(tagService.listTags(bid));

    }
}

2、如果我们只想mock掉RestHighLevelClientProxy类,还想测试ElasticeService类的逻辑,这时候需要处理深度依赖,也就是需要把proxy也注入。

@Slf4j
@ActiveProfiles("dev")
@RunWith(MockitoJUnitRunner.class)
class TagServiceTest {

    /**
     * 这里使用MockBean,tagService中所有方法都会被mock掉.
     */
    @InjectMocks
    private TagService tagService;
    
   @Before
    public void setup() {
    	// 启用注解
        MockitoAnnotations.initMocks(this);
    }

    
    // 注入内层依赖,@Spy跟上一篇文章介绍的@SpyBean类似
    @Spy
    @InjectMocks
	private ElasticeService elasticService;
	
	// mock掉
	@Mock
    private RestHighLevelClientProxy proxy;
    
    @Test
    void buildTagName() {

      Mockito.when(proxy.listTags(Mockito.any())
                .thenReturn(mockResult());
                
        String bid = "45345xclm34kxjL";

        log.info(tagService.listTags(bid));

    }
}

四、小结

至此,我们就实现了不启动SpringBoot项目就可以运行单元测试啦,下一篇《搭建大型分布式服务(四十七)Junit5如何在所有测试用例前执行初始化方法?》

加我加群一起交流学习!更多干货下载、项目源码和大厂内推等着你

你可能感兴趣的:(分布式,java,spring,boot,单元测试,java)