天天看点

Unit Test 5--编写第一个单元测试

大家好,我是神韵,是一个技术&生活博主。出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己。二是希望我的文章可以帮到大家。欢迎来点赞打卡,你们的行动将是我无限的动力。

本篇主题是:编写第一个单元测试

其它文章链接:

Unit Test 1–什么是单元测试

Unit Test 2–IDEA配置并查看单元覆盖率

Unit Test 3–编写单元测试之前需要了解的单元测试框架Mock

Unit Test 4–自动生成单元测试插件之TestMe与Diffblue

Unit Test 6–单元测试踩过的坑

Unit Test 7–单元测试覆盖率表单生成交付,Jacoco的使用

上一篇文章介绍了两个插件,1是Diffbule,2是TestMe,如果用第一款插件可以省事很多。本篇文章主要是介绍单元测试编写,一般建议通过插件生成后再自己进行修改即可。

项目所需依赖

<dependencies>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>3.9.0</version>
    </dependency>

  </dependencies>
           

1、controller层 Unit Test

需要编写单元测试的类UnitTestController.java

@RestController
public class UnitTestController {
    @Autowired
    private UnitTestService unitTestService;

    @PostMapping("/unitTest")
    public UnitTestRspDTO unitTest(@RequestBody UnitTestReqDTO unitTestReqDTO) {
        UnitTestEntity unitTestEntity = unitTestService.queryUnitTestByContent(new UnitTestEntity(unitTestReqDTO.getId(), unitTestReqDTO.getContent()));
        UnitTestRspDTO unitTestRspDTO = new UnitTestRspDTO();
        unitTestRspDTO.setId(unitTestEntity.getId());
        unitTestEntity.setContent(unitTestEntity.getContent());
        return unitTestRspDTO;
    }
}

           

1、Controller层需要通过Mvc去调用,这个类上需要指定加载测试类的容器(controller特有,后面需要Mock Mvc)

Unit Test 5--编写第一个单元测试

2、之前文章提到过,编写单元测试几步走

  1. 准备测试数据 (重)
    Unit Test 5--编写第一个单元测试
  2. Mock需要的对象,Mock具体行为

    需要注入对象MockMvc,通过Mvc调用URL(controller特有)

    Mock 业务类,本来是真实注入业务类UnitService,这里去模拟一个它然后去模拟行为

    Unit Test 5--编写第一个单元测试
    Mock具体行为,返回第一步制造的数据
    Unit Test 5--编写第一个单元测试
  3. 构建请求数据

    post调用/json传参

    Unit Test 5--编写第一个单元测试
    ps:如果真实代码没有里面没有用到传入的参数,也可以用"{}"来传
    Unit Test 5--编写第一个单元测试
    ps:如果是get方法如下
    Unit Test 5--编写第一个单元测试
  4. 做真实调用需要测试的方法调用并比对结果
    Unit Test 5--编写第一个单元测试

至此一个controller测试案例到此结束

完整代码

@RunWith(SpringRunner.class)
@WebMvcTest(UnitTestController.class)
public class UnitTestControllerTest {
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private UnitTestService unitTestService;

    @Test
    public void testUnitTest() throws Exception {
        // mock行为
        when(unitTestService.queryUnitTestByContent(any())).thenReturn(getUnitTestEntity());

        RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/unitTest")
                .contentType(MediaType.APPLICATION_JSON) // 参数接收类型,json
                .content(new ObjectMapper().writeValueAsString(getUnitTestEntity())); // 参数内容 json
        mockMvc.perform(requestBuilder).andExpect(status().isOk()); // 响应验证
    }

    // 测试数据
    private UnitTestEntity getUnitTestEntity() {
        return new UnitTestEntity(1, "test");
    }
}
           

2、Service层 Unit Test

service层不像controller需要从URL入手,这个就简单很多~~

需要编写单元测试的类UnitTestService.java

@Service
public class UnitTestService {
    @Autowired
    private UnitTestRepository unitTestRepository;

    public UnitTestEntity queryUnitTestByContent(UnitTestEntity unitTestEntity) {
        return unitTestRepository.findByContent(unitTestEntity.getContent());
    }
}
           
  1. 准备测试数据
    Unit Test 5--编写第一个单元测试

    2、Mock对象及行为

    对于本身类,需要做调用的通过@InjectMocks去Mock

    这里Mock 其他类没用MockBean,因为没有类上没有启用容器(如WebMvcTest/SpringBootTest…),MockBean会失败~~

    Unit Test 5--编写第一个单元测试
    Unit Test 5--编写第一个单元测试
    3、做真实代码调用
    Unit Test 5--编写第一个单元测试
    4、对比结果
    Unit Test 5--编写第一个单元测试
    完整代码:
@RunWith(MockitoJUnitRunner.class)
public class UnitTestServiceTest {

    @InjectMocks
    private UnitTestService unitTestService;
    @Mock
    private UnitTestRepository unitTestRepository;

    @Test
    public void testQueryUnitTestByContent() {
        // 模拟行为--unitTestRepository.findAll(),并指定返回自己想要的结果
        Mockito.when(unitTestRepository.findByContent(any())).thenReturn(getUnitTestEntity());
        // 调用service方法
        UnitTestEntity unitTestEntity = unitTestService.queryUnitTestByContent(getUnitTestEntity());
        // 校验结果
        Assert.assertEquals(getUnitTestEntity().getId(), unitTestEntity.getId());
    }

    // 制造一个返回结果
    private UnitTestEntity getUnitTestEntity() {
        return new UnitTestEntity(1, "test");
    }
}
           

3、Dao层

这里我们使用的是JPA,没有用到这一层的单元测试,略…

4、测试结果

好,现在我们来运行一下单元测试案例,看下我们编写了两个测试类的效果,具体前面怎么配置和运行已经写过文章

Unit Test 5--编写第一个单元测试

结果如下:

controller/service覆盖率为100%~

Unit Test 5--编写第一个单元测试