搭建大型分布式服务(四十五)SpringBoot 单元测试Mock如何根据参数返回结果?

系列文章目录

搭建大型分布式服务(四十五)SpringBoot 单元测试Mock如何根据参数返回结果?_第1张图片

文章目录

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


前言

SpringBoot支持集成Mockito做单元测试,我们在本地做单元测试测试的时候,经常因为环境等问题需要mock掉外部方法(远程调用、DB查询等),在Mock掉的同时,如果也想根据入参条件返回mock结果,需要怎样做呢?


一、本文要点

接前文,我们已经已介绍SringBoot如果做单元测试了,本文介绍在两种mock模式下,怎样根据入参返回自定义mock结果。
系列文章完整目录

  • SpringBooot 单元测试
  • Mockito 单元测试
  • MockBean、SpyBean 单元测试
  • 根据入参自定义mock结果

二、开发环境

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

三、编写真实Service类TagService.java

编写一个方法,无实际意义,模拟真实应用场景。

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

	// 这里模拟超级复杂的远程方法调用
    public String buildTagName(String bId) {
        return "";
    }
}

四、编写测试类

1、@MockBean 通常使用when().thenAnswer()模式来测试。

@Slf4j
@ActiveProfiles("dev")
@ExtendWith(SpringExtension.class)
@SpringBootTest
class TagServiceTest {

    /**
     * 这里使用MockBean,tagService中所有方法都会被mock掉.
     */
    @MockBean
    private TagService tagService;
    
    @Test
    void buildTagName() {

        String bid = "45345xclm34kxjL";

        // 这段代码的含义:当执行tagService.buildTagName(bid)方法时,将会被thenAnswer()中的内容替换
        // thenAnswer()中的方法:根据入参,判断是否为正确bId,是的话返回正确的mock结果,否则返回错误的mock结果
        // 这里只是随便举例,可以根据实际情况编写mock逻辑
        Mockito.when(tagService.buildTagName(bid)).thenAnswer(
                invocation -> Optional.of(invocation.getArgument(0))
                        .filter(x -> x.equals(bid)).map(x -> "TAG" + x).orElse("ERROR"));

        // 模拟调用buildTagName()方法
        Assertions.assertEquals(tagService.buildTagName(bid), "TAG" + bid);
        Assertions.assertNotEquals(tagService.buildTagName("error bid"), "TAG" + bid);

    }
}

2、@SpyBean 需要使用doAnswer().when()模式来测试。

@Slf4j
@ActiveProfiles("dev")
@ExtendWith(SpringExtension.class)
@SpringBootTest
class TagServiceTest {

    /**
     * 这里使用MockBean,tagService中所有方法都会被mock掉.
     */
    @MockBean
    private TagService tagService;
    
    @Test
    void buildTagName() {

        String bid = "45345xclm34kxjL";

        // 这段代码的含义:当执行tagService.buildTagName(bid)方法时,将会被thenAnswer()中的内容替换
        // thenAnswer()中的方法:根据入参,判断是否为正确bId,是的话返回正确的mock结果,否则返回错误的mock结果
        // 这里只是随便举例,可以根据实际情况编写mock逻辑
        Mockito.doAnswer(invocation -> Optional.of(invocation.getArgument(0))
                .filter(x -> x.equals(bid)).map(x -> "TAG" + x).orElse("ERROR"))
                .when(tagService).buildTagName(bid);

        // 模拟调用buildTagName()方法
        Assertions.assertEquals(tagService.buildTagName(bid), "TAG" + bid);
        Assertions.assertNotEquals(tagService.buildTagName("error bid"), "TAG" + bid);

    }
}

四、小结

至此,我们就实现了通过入参来自定义mock结果啦,下一篇《搭建大型分布式服务(三十四)Junit5如何在所有测试用例前执行初始化方法?》

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

搭建大型分布式服务(四十五)SpringBoot 单元测试Mock如何根据参数返回结果?_第2张图片 搭建大型分布式服务(四十五)SpringBoot 单元测试Mock如何根据参数返回结果?_第3张图片 搭建大型分布式服务(四十五)SpringBoot 单元测试Mock如何根据参数返回结果?_第4张图片

你可能感兴趣的:(分布式,日常笔记,单元测试,spring,boot,mock,mockito)