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

本文详细介绍了如何在Spring Boot项目中编写Controller和Service层的单元测试,包括使用Mockito进行对象模拟、MockMvc进行Controller测试以及通过@Test注解执行测试用例。示例代码展示了如何设置测试数据、模拟对象行为并验证方法调用结果,帮助提升代码覆盖率。
摘要由CSDN通过智能技术生成

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

其它文章链接:
Unit Test 1–什么是单元测试
Unit Test 2–IDEA配置并查看单元覆盖率
Unit Test 3–编写单元测试之前需要了解的单元测试框架Mock
Unit Test 4–自动生成单元测试插件之TestMe与Diffblue
Unit Test 6–单元测试踩过的坑
Unit Test 7–单元测试覆盖率表单生成交付,Jacoco的使用
Controller 层的单元测试怎么写?
同一个类的方法怎么Mock?spy函数啦

上一篇文章介绍了两个插件,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

2021/11/24 add - 最新参考:Controller 层的单元测试怎么写?
因为如果通过MVC是比较复杂的,但是应该是最正确的方式,但是上面链接的也可以,简单快捷。

需要编写单元测试的类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)
在这里插入图片描述
2、之前文章提到过,编写单元测试几步走

  1. 准备测试数据 (重)
    在这里插入图片描述

  2. Mock需要的对象,Mock具体行为
    需要注入对象MockMvc,通过Mvc调用URL(controller特有)
    Mock 业务类,本来是真实注入业务类UnitService,这里去模拟一个它然后去模拟行为
    在这里插入图片描述
    Mock具体行为,返回第一步制造的数据
    在这里插入图片描述

  3. 构建请求数据
    post调用/json传参
    在这里插入图片描述
    ps:如果真实代码没有里面没有用到传入的参数,也可以用"{}"来传
    在这里插入图片描述ps:如果是get方法如下
    在这里插入图片描述

  4. 做真实调用需要测试的方法调用并比对结果
    在这里插入图片描述

至此一个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. 准备测试数据
    在这里插入图片描述
    2、Mock对象及行为
    对于本身类,需要做调用的通过@InjectMocks去Mock
    这里Mock 其他类没用MockBean,因为没有类上没有启用容器(如WebMvcTest/SpringBootTest…),MockBean会失败~~
    在这里插入图片描述
    在这里插入图片描述
    3、做真实代码调用
    在这里插入图片描述
    4、对比结果
    在这里插入图片描述
    完整代码:
@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、测试结果

好,现在我们来运行一下单元测试案例,看下我们编写了两个测试类的效果,具体前面怎么配置和运行已经写过文章
在这里插入图片描述
结果如下:
controller/service覆盖率为100%~
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,我理解了你的问题。以下是一个可能的解决方案: 假设我们要测试的方法是一个名为 `computeSum` 的静态方法,其功能是计算给定整数数组中所有元素的总和。我们可以使用 JUnit 框架来编写单元测试。以下是一个示例测试类的代码: ``` import org.junit.Test; import static org.junit.Assert.*; public class MyMathTest { @Test public void testComputeSum() { int[] arr1 = {1, 2, 3, 4, 5}; int[] arr2 = {-1, 0, 1}; int[] arr3 = {0}; // Test case 1 int expected1 = 15; int actual1 = MyMath.computeSum(arr1); assertEquals(expected1, actual1); // Test case 2 int expected2 = 0; int actual2 = MyMath.computeSum(arr2); assertEquals(expected2, actual2); // Test case 3 int expected3 = 0; int actual3 = MyMath.computeSum(arr3); assertEquals(expected3, actual3); } } ``` 在这个示例测试类中,我们定义了一个名为 `testComputeSum` 的测试方法。该方法包含三个测试用例,分别测试不同的输入数组。在每个测试用例中,我们通过调用 `MyMath.computeSum` 方法来计算实际结果,并将其与预期结果进行比较。如果实际结果与预期结果不相等,则测试失败。 我们可以使用 `assertEquals` 方法来进行比较。该方法将两个参数进行比较,并在它们不相等时抛出一个 `AssertionError` 异常。如果所有测试用例通过,测试类将显示“OK”消息。 总之,这是一个基本的示例,你可以根据自己的需要进行更改和调整。希望这可以帮助你开始编写单元测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值